/* ==========================================================================
   PORTAFOLIO · Sistema visual
   public/assets/css/base.css
   --------------------------------------------------------------------------
   Identidad editorial en blanco y negro. La decisión central: el color no
   compite con las fotografías. No hay acentos de marca, no hay degradados de
   color y no hay sombras de color: sólo tinta, papel y la fotografía.

   Excepción deliberada: un único verde de contacto para el botón de WhatsApp,
   porque ahí el color cumple una función (se reconoce sin leerlo) y no
   compite con nada más.
   ========================================================================== */

:root {
  /* --- Color: papel y tinta --- */
  --papel: #fbfaf8;
  --papel-2: #f2f0ec;
  --tinta: #12100e;
  --tinta-2: #2c2824;
  --gris: #6f6a63;
  --gris-2: #a8a29a;
  --linea: #ded9d1;
  --linea-fuerte: #c9c2b8;

  /* Único color funcional del sitio. */
  --wa: #1f8a4c;
  --wa-hover: #17703d;

  /* --- Tipografía ---
     Serif de alto contraste para los títulos: es lo que da el tono editorial.
     Sans humanista para interfaz y textos: se lee bien en tamaños pequeños. */
  --serif: 'Cormorant Garamond', 'Times New Roman', Times, serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Escala fluida: evita media queries para el tamaño del texto. */
  --t-xs: clamp(0.68rem, 0.66rem + 0.10vw, 0.75rem);
  --t-sm: clamp(0.80rem, 0.78rem + 0.12vw, 0.88rem);
  --t-base: clamp(0.94rem, 0.90rem + 0.20vw, 1.05rem);
  --t-md: clamp(1.10rem, 1.02rem + 0.40vw, 1.35rem);
  --t-lg: clamp(1.45rem, 1.20rem + 1.10vw, 2.10rem);
  --t-xl: clamp(2.00rem, 1.40rem + 2.60vw, 3.60rem);
  --t-2xl: clamp(2.60rem, 1.50rem + 4.80vw, 5.60rem);
  --t-3xl: clamp(3.20rem, 1.40rem + 7.20vw, 8.00rem);

  --e-titulo: -0.015em;
  --e-etiqueta: 0.18em;

  /* --- Espacio --- */
  --e-1: 0.25rem;
  --e-2: 0.5rem;
  --e-3: 0.75rem;
  --e-4: 1rem;
  --e-5: 1.5rem;
  --e-6: 2.5rem;
  --e-7: 4rem;
  --e-8: 6rem;
  --e-9: 9rem;

  --margen: clamp(1.25rem, 5vw, 5rem);
  --ancho-max: 1560px;
  --ancho-texto: 62ch;

  /* --- Movimiento ---
     Corto y discreto. Un portafolio no necesita animaciones largas: la
     atención tiene que ir a la imagen. */
  --d-rapido: 180ms;
  --d-medio: 420ms;
  --d-lento: 900ms;
  --curva: cubic-bezier(0.22, 0.61, 0.36, 1);
  --curva-salida: cubic-bezier(0.16, 1, 0.30, 1);

  --cabecera-alto: 4.5rem;
}

/* ==========================================================================
   Base
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--cabecera-alto);
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--sans);
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--tinta);
  background: var(--papel);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* El atributo hidden debe ganar siempre. Sin esto, cualquier componente con
   display:flex o grid lo anula y el elemento sigue visible. */
[hidden] {
  display: none !important;
}

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: var(--e-titulo);
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

figure, blockquote {
  margin: 0;
}

ul, ol, dl, dd {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 4px;
}

.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;
}

.saltar {
  position: absolute;
  top: -100px;
  left: var(--e-4);
  z-index: 100;
  padding: var(--e-3) var(--e-5);
  background: var(--tinta);
  color: var(--papel);
  font-size: var(--t-sm);
}

.saltar:focus {
  top: var(--e-4);
}

/* ==========================================================================
   Cabecera
   ========================================================================== */

.cabecera {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  height: var(--cabecera-alto);
  display: flex;
  align-items: center;
  /* Fondo translúcido con desenfoque: la cabecera se lee sobre la fotografía
     sin necesidad de una barra opaca que corte la imagen. */
  background: rgb(251 250 248 / 0.82);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom: 1px solid transparent;
  transition: border-color var(--d-medio) var(--curva),
              background-color var(--d-medio) var(--curva);
}

/* Sobre la portada a pantalla completa la cabecera es transparente y clara. */
.cabecera--sobre-foto {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: var(--papel);
}

.cabecera--sobre-foto .cabecera__enlace {
  color: rgb(251 250 248 / 0.85);
}

.cabecera--con-borde {
  border-bottom-color: var(--linea);
}

.cabecera__interior {
  width: 100%;
  max-width: var(--ancho-max);
  margin: 0 auto;
  padding: 0 var(--margen);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
}

.marca {
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  min-width: 0;
}

/* El logotipo entregado es de tinta oscura sobre fondo transparente. Sobre la
   fotografía de portada no se vería, así que se intercambia por la versión
   blanca que genera tools/preparar_logos.py. El cambio lo hace el JS al
   alternar la clase cabecera--sobre-foto. Aquí NO se aplica ningún filtro:
   el archivo original tenía fondo blanco opaco y invertirlo convertía el
   recuadro en negro. */
.marca__logo {
  height: 26px;
  width: auto;
}

.marca__nombre {
  font-family: var(--serif);
  font-size: var(--t-md);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.marca__nombre--oculto {
  display: none;
}

.navegacion {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2.5rem);
}

.cabecera__enlace {
  font-size: var(--t-xs);
  letter-spacing: var(--e-etiqueta);
  text-transform: uppercase;
  color: var(--gris);
  position: relative;
  padding: var(--e-2) 0;
  transition: color var(--d-rapido) var(--curva);
}

/* Subrayado que crece desde la izquierda: el gesto mínimo que indica
   interactividad sin añadir cajas ni botones. */
.cabecera__enlace::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-medio) var(--curva);
}

.cabecera__enlace:hover,
.cabecera__enlace.es-activo {
  color: var(--tinta);
}

.cabecera--sobre-foto .cabecera__enlace:hover,
.cabecera--sobre-foto .cabecera__enlace.es-activo {
  color: var(--papel);
}

.cabecera__enlace:hover::after,
.cabecera__enlace.es-activo::after {
  transform: scaleX(1);
}

.cabecera__boton-menu {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
}

.cabecera__raya {
  display: block;
  width: 22px;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--d-medio) var(--curva), opacity var(--d-medio) var(--curva);
}

.cabecera__boton-menu[aria-expanded="true"] .cabecera__raya:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.cabecera__boton-menu[aria-expanded="true"] .cabecera__raya:nth-child(2) {
  opacity: 0;
}

.cabecera__boton-menu[aria-expanded="true"] .cabecera__raya:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

@media (max-width: 800px) {
  .cabecera__boton-menu {
    display: flex;
    /* Por encima del panel de navegación: si no, el propio menú tapa el botón
       que lo abre y no se puede cerrar. */
    position: relative;
    z-index: 2;
  }

  .marca {
    /* Mismo motivo que el botón, y era el fallo que hacía desaparecer el
       logotipo: el panel de navegación es un elemento POSICIONADO y, por
       orden de apilado, se pintaba encima de la marca, que era estática. El
       logotipo existía y estaba visible según sus estilos, pero quedaba
       tapado por el menú. */
    position: relative;
    z-index: 2;
  }

  .navegacion {
    position: fixed;
    inset: 0;
    /* z-index positivo: el panel se pinta SOBRE el contenido. Estaba en -1 y
       quedaba detrás de la fotografía de portada, así que el menú se abría
       pero no se veía. */
    z-index: 1;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: var(--e-2);
    padding: calc(var(--cabecera-alto) + var(--e-5)) var(--margen) var(--e-7);
    background: var(--papel);
    color: var(--tinta);
    opacity: 0;
    visibility: hidden;
    overflow-y: auto;
    transition: opacity var(--d-medio) var(--curva), visibility var(--d-medio);
  }

  .navegacion.es-abierta {
    opacity: 1;
    visibility: visible;
  }

  /* La cabecera queda por encima del panel, con fondo sólido, para que el
     logotipo y el botón de cerrar se vean siempre. */
  body.menu-abierto .cabecera {
    background: var(--papel);
    color: var(--tinta);
    z-index: 3;
  }

  body.menu-abierto .marca__logo {
    /* El logotipo blanco sobre el fondo claro del menú desaparecía por
       completo. Al abrir el menú se usa siempre la versión oscura. */
    visibility: visible;
  }

  /* Los enlaces de navegación heredaban el color claro de la cabecera
     transparente (`cabecera--sobre-foto`), así que sobre el fondo papel del
     menú quedaban blancos sobre blanco: no se veían. Aquí se fuerza la tinta
     y se recupera el tamaño grande que corresponde a un menú a pantalla
     completa. */
  body.menu-abierto .navegacion .cabecera__enlace,
  .navegacion.es-abierta .cabecera__enlace {
    color: var(--tinta);
    font-size: var(--t-md);
    letter-spacing: 0.1em;
    padding: var(--e-2) 0;
  }

  body.menu-abierto .navegacion .cabecera__enlace::after,
  .navegacion.es-abierta .cabecera__enlace::after {
    background: var(--tinta);
  }

  body.menu-abierto .navegacion__titulo-grupo {
    color: var(--gris);
  }
}

/* ==========================================================================
   Menú móvil: grupos y lista de series
   ========================================================================== */

.navegacion__grupo {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  width: 100%;
}

.navegacion__titulo-grupo {
  font-size: var(--t-xs);
  letter-spacing: var(--e-etiqueta);
  text-transform: uppercase;
  color: var(--gris);
  margin-bottom: var(--e-2);
}

/* Lista de series dentro del menú móvil. */
.navegacion__series {
  display: flex;
  flex-direction: column;
  gap: 0;
  width: 100%;
}

.navegacion__serie {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
  padding: var(--e-2) 0;
  border-bottom: 1px solid var(--linea);
  font-family: var(--serif);
  font-size: var(--t-md);
  color: var(--tinta);
  transition: opacity var(--d-rapido) var(--curva);
}

.navegacion__serie:hover {
  opacity: 0.55;
}

.navegacion__serie-cuenta {
  font-family: var(--sans);
  font-size: var(--t-xs);
  letter-spacing: var(--e-etiqueta);
  color: var(--gris-2);
  white-space: nowrap;
}

.navegacion__pie {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  margin-top: var(--e-3);
  width: 100%;
}

/* En escritorio cambia la estructura del menú.
   Los bloques que se añadieron para el menú móvil (lista de series, botones de
   WhatsApp y compartir) tienen que desaparecer, y el grupo de enlaces debe
   volver a ser una fila: si se deja como columna, la cabecera de escritorio
   apila «Proyectos / Sobre mí / Contacto» en vertical y se rompe.

   `display: contents` hace que los enlaces del grupo participen directamente
   del flex de `.navegacion`, sin añadir una caja intermedia.

   ORDEN IMPORTANTE: el grupo de series también lleva la clase
   `.navegacion__grupo`, así que ambas reglas tienen la misma especificidad.
   Las que ocultan van DESPUÉS de la de `contents`: al revés, `display: contents`
   ganaba y la lista entera de series se dibujaba dentro de la cabecera de
   escritorio. */
@media (min-width: 801px) {
  .navegacion__grupo {
    display: contents;
  }

  .navegacion__grupo--series,
  .navegacion__pie {
    display: none;
  }
}

/* ==========================================================================
   Tipografía de sección
   ========================================================================== */

.etiqueta {
  display: block;
  font-size: var(--t-xs);
  letter-spacing: var(--e-etiqueta);
  text-transform: uppercase;
  color: var(--gris);
}

.titulo-seccion {
  font-size: var(--t-xl);
}

.texto-entrada {
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--tinta-2);
  max-width: var(--ancho-texto);
}

/* ==========================================================================
   Botones
   ========================================================================== */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: 46px;
  padding: var(--e-3) var(--e-5);
  font-size: var(--t-xs);
  letter-spacing: var(--e-etiqueta);
  text-transform: uppercase;
  border: 1px solid var(--tinta);
  border-radius: 0;
  background: var(--tinta);
  color: var(--papel);
  transition: background-color var(--d-rapido) var(--curva),
              color var(--d-rapido) var(--curva),
              border-color var(--d-rapido) var(--curva);
}

.boton:hover {
  background: transparent;
  color: var(--tinta);
}

.boton--fantasma {
  background: transparent;
  color: var(--tinta);
  border-color: var(--linea-fuerte);
}

.boton--fantasma:hover {
  border-color: var(--tinta);
  background: transparent;
}

.boton--claro {
  background: var(--papel);
  color: var(--tinta);
  border-color: var(--papel);
}

.boton--claro:hover {
  background: transparent;
  color: var(--papel);
  border-color: var(--papel);
}

.boton--whatsapp {
  background: var(--wa);
  border-color: var(--wa);
  color: #fff;
}

.boton--whatsapp:hover {
  background: var(--wa-hover);
  border-color: var(--wa-hover);
  color: #fff;
}

/* Variante compacta para el menú móvil, donde el espacio vertical escasea. */
.boton--compacto {
  min-height: 40px;
  padding: var(--e-2) var(--e-4);
  font-size: 0.66rem;
}

/* ==========================================================================
   Aparición al desplazar
   ========================================================================== */

.revela {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--d-lento) var(--curva-salida),
              transform var(--d-lento) var(--curva-salida);
}

.revela.es-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .revela {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ==========================================================================
   Pie
   ========================================================================== */

.pie {
  border-top: 1px solid var(--linea);
  padding: var(--e-8) var(--margen) var(--e-6);
  margin-top: var(--e-9);
}

.pie__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: var(--e-6);
  align-items: start;
}

.pie__nombre {
  font-family: var(--serif);
  font-size: var(--t-lg);
  margin-bottom: var(--e-2);
}

.pie__nota,
.pie__ciudad {
  font-size: var(--t-sm);
  color: var(--gris);
}

.pie__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
}

.pie__redes {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  font-size: var(--t-sm);
}

.pie__redes a {
  color: var(--gris);
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: color var(--d-rapido) var(--curva), border-color var(--d-rapido) var(--curva);
}

.pie__redes a:hover {
  color: var(--tinta);
  border-bottom-color: var(--tinta);
}

.pie__legal {
  max-width: var(--ancho-max);
  margin: var(--e-7) auto 0;
  padding-top: var(--e-4);
  border-top: 1px solid var(--linea);
  font-size: var(--t-xs);
  color: var(--gris-2);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--e-3);
}

/* ==========================================================================
   Aviso de sistema (mensajes de error o estado)
   ========================================================================== */

.aviso {
  position: fixed;
  left: 50%;
  bottom: var(--e-5);
  transform: translate(-50%, 20px);
  z-index: 200;
  padding: var(--e-3) var(--e-5);
  background: var(--tinta);
  color: var(--papel);
  font-size: var(--t-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-medio) var(--curva), transform var(--d-medio) var(--curva);
}

.aviso.es-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

.aviso--error {
  background: #8c1d1d;
}
