/* =============================================================================
 * public-layout.css — Layout de la web publica (cabecera, pie, banner de cookies, legal).
 *
 * EXTERNALIZADO desde el bloque `<style>` de `templates/public/_layout.html` (ola F1 del
 * endurecimiento CSP, 2026-07-26). Vivía inline en la plantilla, lo que obligaba
 * a `style-src 'unsafe-inline'` en la Content-Security-Policy: con esa concesión
 * un XSS podía inyectar CSS y exfiltrar datos por selectores + `url()`. Ahora la
 * hoja se sirve de `/static/css/` (mismo origen) y la CSP puede exigir
 * `style-src-elem 'self'` sin ninguna excepción.
 *
 * REGLA: no volver a meter `<style>` en la plantilla — el test
 * `crates/web/tests/csp_no_inline_style_test.rs` lo rompe a propósito.
 * El ORDEN de carga importa: este `<link>` va donde estaba el `<style>`, para
 * que la cascada (quién gana sobre `brand.css`) no cambie de aspecto.
 * ========================================================================== */
:root {
  --bg: #faf8f5;
  --surface: #ffffff;
  --surface-2: #f1ede5;
  --text: #1c1c1e;
  --text-soft: #5a5a60;
  --primary: #c14b6b;
  --primary-hover: #aa3f5d;
  --accent: #2f5ad0;
  --border: #e2dccf;
  --radius: 8px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #131318;
    --surface: #1c1c22;
    --surface-2: #25252d;
    --text: #ececef;
    --text-soft: #a4a4ab;
    --border: #2e2e36;
  }
}
*, *::before, *::after { box-sizing: border-box; }
html { color-scheme: light dark; }
body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", "Inter", "Helvetica Neue", sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.55;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
a { color: var(--primary-text); }
header.site-header {
  padding: 1rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  /* Contexto de posicionamiento para el desplegable móvil (position:absolute
     del `.nav-collapse.open`); en desktop no altera nada. */
  position: relative;
}
/* Lockup de cabecera: símbolo (SVG) + wordmark HTML. El wordmark va en
   HTML (no dentro del SVG) a propósito: un <img> SVG está aislado y NO
   carga la fuente Fraunces de marca, así que caería a serif del sistema.
   En HTML sí respeta --font-display (Fraunces, vía brand.css) y el coral. */
header.site-header .logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1;
  text-decoration: none;
  color: var(--text);
}
header.site-header .logo img {
  display: block;
  height: 28px;   /* altura mínima legible del símbolo */
  width: auto;
}
header.site-header .logo .wordmark {
  font-family: var(--font-display, "Fraunces", Georgia, serif);
  font-weight: 600;
  letter-spacing: -0.01em;
}
/* El "Vibra" en coral de marca; "Nos" hereda el color de texto. */
header.site-header .logo .brand-accent { color: var(--primary); }
header.site-header nav {
  display: flex;
  gap: 1.25rem;
  align-items: center;
  flex-wrap: wrap;
}
header.site-header nav a {
  color: var(--text-soft);
  text-decoration: none;
  font-size: 0.95rem;
}
header.site-header nav a:hover { color: var(--text); }
header.site-header .auth-actions {
  display: flex;
  gap: 0.5rem;
}
/* ── Acciones de ENTRADA para anónimos (crear cuenta / iniciar sesión) ──
   Van FUERA del envoltorio colapsable a propósito: antes el único acceso a
   login vivía dentro del desplegable ☰ y, en móvil, quedaba como último
   elemento tras 8 enlaces → efectivamente invisible. La queja del dueño era
   literalmente "el login está oculto". Al sacarlas del `.nav-collapse`
   siguen visibles en la barra superior con el menú cerrado, en cualquier
   ancho. Jerarquía: "Crear cuenta" primaria (coral), "Iniciar sesión"
   secundaria (outline) — el registro es el objetivo de negocio, pero quien
   ya tiene cuenta encuentra su puerta de un vistazo. */
header.site-header .auth-actions.auth-entry {
  flex-wrap: nowrap;
  align-items: center;
}
/* ── Menú responsive (hamburguesa) ──────────────────────────────────────
   DESKTOP (por defecto): `.nav-collapse` usa `display: contents`, es decir
   es un envoltorio TRANSPARENTE: sus hijos (<nav> y `.auth-actions`)
   participan directamente en el flex del header, EXACTAMENTE como antes de
   agruparlos → cero regresión visual por encima del breakpoint. El botón ☰
   va oculto. El mecanismo es JS propio (nav-menu.js), NO Alpine: la CSP
   `script-src 'self'` sin `unsafe-eval` rompe el evaluador de Alpine. */
header.site-header .nav-collapse { display: contents; }
/* Botón hamburguesa: oculto salvo en móvil-con-JS (ver media query). El
   icono ☰ se dibuja con CSS (span + ::before/::after) → sin imagen externa.
   min 44px de lado = objetivo táctil accesible. */
.nav-toggle {
  display: none;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  color: var(--text);
}
.nav-toggle:hover { background: var(--surface-2); }
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  content: "";
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before { position: absolute; top: -6px; }
.nav-toggle-bars::after  { position: absolute; top:  6px; }

/* MÓVIL: solo cuando nav-menu.js ha marcado el header (`data-nav-enhanced`).
   Sin JS, este bloque no aplica y el menú se ve expandido como siempre
   (fallback sin botón muerto). Breakpoint 900px: el header público tiene
   ~8-11 enlaces + acciones de sesión, así que necesita colapsar antes que
   una barra corta (por eso 900 y no 768). */
@media (max-width: 899.98px) {
  header.site-header[data-nav-enhanced] .nav-toggle { display: inline-flex; }
  /* El envoltorio deja de ser transparente y pasa a ser un panel desplegable
     anclado bajo el header. Oculto por defecto; visible al añadir `.open`. */
  header.site-header[data-nav-enhanced] .nav-collapse {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 12px 28px rgba(0,0,0,0.18);
    padding: 0.5rem 0.75rem 0.75rem;
    z-index: 30;
  }
  header.site-header[data-nav-enhanced] .nav-collapse.open { display: flex; }
  /* Dentro del panel: enlaces a ancho completo, apilados y con objetivo
     táctil ≥44px. El overlay es `position:absolute` → NO empuja el contenido
     ni bloquea el scroll de la página. */
  header.site-header[data-nav-enhanced] .nav-collapse nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
  }
  header.site-header[data-nav-enhanced] .nav-collapse nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 0.5rem;
    font-size: 1rem;
  }
  header.site-header[data-nav-enhanced] .nav-collapse .auth-actions {
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border);
  }
  header.site-header[data-nav-enhanced] .nav-collapse .auth-actions .btn {
    text-align: center;
  }
}

/* ── Compactado móvil de la barra superior ─────────────────────────────
   Aquí NO se exige `data-nav-enhanced`: las acciones de entrada están fuera
   del desplegable, así que deben caber también si el JS no carga. En 360px
   de ancho el presupuesto es justo (logo + 2 botones + ☰), de modo que se
   recorta el padding del header y se encoge el lockup del logo. */
@media (max-width: 899.98px) {
  header.site-header { padding: 0.75rem 1rem; gap: 0.5rem; }
  header.site-header .logo { font-size: 1.12rem; gap: 0.35rem; }
  header.site-header .logo img { height: 24px; }
  header.site-header .auth-actions.auth-entry { gap: 0.4rem; }
  header.site-header .auth-actions.auth-entry .btn {
    padding: 0.5rem 0.7rem;
    font-size: 0.85rem;
    /* Sin salto de línea: "Iniciar sesión" partido en dos líneas descuadra
       la barra y en algunos idiomas (de-DE, fi-FI) es aún más largo. */
    white-space: nowrap;
  }
}
/* Por debajo de ~480px las dos etiquetas ya no caben junto al logo en
   idiomas largos. En vez de recortarlas o esconderlas otra vez, se deja que
   el header (flex-wrap:wrap) las mande a una SEGUNDA FILA a ancho completo:
   siguen 100% visibles, con objetivo táctil grande, y el logo/☰ conservan
   la primera fila. `order:3` garantiza que caen detrás del botón ☰. */
@media (max-width: 479.98px) {
  header.site-header .auth-actions.auth-entry {
    order: 3;
    flex: 1 1 100%;
  }
  header.site-header .auth-actions.auth-entry .btn {
    flex: 1 1 0;
    text-align: center;
    padding: 0.6rem 0.5rem;
  }
}
.btn {
  cursor: pointer;
  border: 0;
  padding: 0.55rem 1.1rem;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
  font-size: 0.92rem;
}
/* PENDIENTE DE DECISIÓN (auditoría de contraste 2026-07-20): blanco sobre el
   coral vivo da 3,36:1 en claro y 2,95:1 en oscuro; el rótulo de un botón es
   TEXTO y pide 4,5:1. Las salidas son oscurecer SOLO el relleno del botón
   (con #CF4A29 el blanco ya da 4,50 y el tono sigue siendo el mismo coral) o
   rotular en carbón (#2C2C2A sobre el coral actual da 4,17 — tampoco llega).
   Se deja intacto: es el botón más visible del producto y cambiarlo se nota.
   Decisión de producto. */
.btn.primary { background: var(--primary); color: #fff; }
.btn.primary:hover { background: var(--primary-hover); }
.btn.outline { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn.outline:hover { background: var(--surface-2); }
main.site-main {
  flex: 1;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 4rem;
}
section.hero {
  text-align: center;
  padding: 2.5rem 0 2rem;
}
section.hero h1 {
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  margin: 0 0 1rem;
}
section.hero p.lead {
  font-size: 1.15rem;
  color: var(--text-soft);
  max-width: 620px;
  margin: 0 auto 1.5rem;
}
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  margin: 2rem 0;
}
.feature {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
}
.feature h3 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}
.feature p { margin: 0; color: var(--text-soft); }
.card-content {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem 1.75rem;
  margin-bottom: 1.5rem;
}
.card-content h2 { margin-top: 0; }
footer.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 2rem 1.5rem;
  color: var(--text-soft);
  font-size: 0.9rem;
}
footer.site-footer .footer-grid {
  max-width: 960px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1.5rem;
}
footer.site-footer h4 { color: var(--text); margin: 0 0 0.5rem; font-size: 0.95rem; }
footer.site-footer a { color: var(--text-soft); text-decoration: none; display: block; padding: 0.15rem 0; }
footer.site-footer a:hover { color: var(--text); }
footer.site-footer .lang-selector form { display: inline-flex; gap: 0.4rem; align-items: center; }
footer.site-footer select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.3rem 0.5rem;
  font: inherit;
  font-size: 0.85rem;
}
.cookie-banner {
  position: fixed;
  bottom: 1rem;
  left: 1rem;
  right: 1rem;
  max-width: 720px;
  margin: 0 auto;
  padding: 1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(0,0,0,0.18);
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
  z-index: 100;
}
.cookie-banner p { margin: 0; flex: 1 1 280px; font-size: 0.9rem; }
.cookie-banner .actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.legal-text h1 { margin-top: 0; }
.legal-text h2 { margin-top: 2rem; }
.legal-text p { color: var(--text-soft); }
@media (max-width: 640px) {
  footer.site-footer .footer-grid { grid-template-columns: 1fr; }
}
