/* Generado por scripts/build.mjs: brand-tokens.css + fonts.css + site.css.
   No se edita aqui. Los originales viven en src/assets/css/. */

/* brand-tokens.css */
/* ============================================================
   Loden — brand tokens
   Fuente única de la identidad visual. Si un color, una fuente
   o un espaciado no está aquí, no se usa.

   Hereda de este archivo:
     · el sitio (src/assets/css/site.css)
     · brand-template.html (imágenes de los posts del motor)
     · la plantilla del reporte mensual del cliente
     · las plantillas de artículo

   Última revisión: septiembre 2026
   ============================================================ */

:root {

  /* ---------- COLOR ----------
     La regla, en una línea:
       tinta = la marca · terracota = el acento · menta = señal viva
     Si un color aparece fuera de su papel, está mal puesto.       */

  /* La marca. Texto, titulares, paneles oscuros, el logotipo. */
  --ink:          #12302F;   /* 13.3:1 sobre paper — cuerpo de texto */
  --ink-soft:     #55706E;   /* 5.1:1 sobre paper — texto secundario */

  /* El acento cálido. El punto del logo, enlaces, filos, botones. */
  --ember:        #A8512C;   /* 5.4:1 con texto blanco — apto para botones */
  --ember-soft:   #E8A882;   /* solo fondos y lavados; nunca texto */

  /* Señal viva. SOLO donde algo está ocurriendo:
     indicadores, datos en vivo, estados del sistema, el punto del logo. */
  --glow:         #7FE3D0;   /* usar con texto oscuro encima */

  /* Superficies. */
  --paper:        #FBF8F3;   /* fondo del sitio, crema cálido */
  --paper-doc:    #FDFCF9;   /* fondo de documentos, más suave */
  --paper-2:      #F2EDE4;   /* tablas, bloques de código, cajas */
  --mist:         #E2DACE;   /* bordes, reglas, separadores */

  /* Secundario. Paneles, detalles, fondos oscuros alternativos. */
  --petrol:       #0E5C5E;   /* 7.7:1 con texto blanco */
  --petrol-light: #14807E;   /* nunca para texto pequeño: 4.5:1, justo bajo AA */

  /* Fondo "amanecer": menta arriba a la derecha, albaricoque a la
     izquierda, crema de base. Solo en el sitio y en portadas.
     Nunca dentro de documentos de texto. */
  --wash-mint:    #BFEEDF;
  --wash-apricot: #F7DAC4;


  /* ---------- TIPOGRAFÍA ---------- */

  /* Web */
  --font-display: 'Fraunces', Georgia, serif;        /* titulares y logotipo */
  --font-body:    'Hanken Grotesk', system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;  /* etiquetas */

  /* Documentos y PDF */
  --font-doc-head: 'Space Grotesk', sans-serif;
  --font-doc-body: 'Inter', sans-serif;


  /* ---------- ESCALA ---------- */

  --step-1:  0.5rem;
  --step-2:  1rem;
  --step-3:  1.5rem;
  --step-4:  2.5rem;
  --step-5:  4rem;

  --radius-sm: 6px;
  --radius:    12px;
  --radius-pill: 999px;

  --measure: 68ch;        /* ancho máximo de lectura cómoda */
  --content-max: 1120px;  /* ancho del contenedor */
}


/* ============================================================
   REGLAS DE USO — no son decorativas, son la disciplina

   1. El menta nunca es decoración. Si el elemento no representa
      algo que está pasando ahora, no lleva menta.

   2. La terracota es el único color cálido. Por eso la mirada va
      directo a ella: úsala donde quieras que el ojo caiga.

   3. Los documentos van en blanco o --paper-doc, con el logotipo
      arriba, y el color solo en filos y cabeceras. El degradado
      "amanecer" vive en el sitio, nunca en un documento de texto.

   4. Nunca texto pequeño sobre --petrol-light, --ember-soft ni
      --glow: no alcanzan el contraste mínimo.

   5. Cada cliente tendrá su propio archivo de tokens con la misma
      estructura. Este es el de Loden (cliente #0) y sirve de
      plantilla: se copian los nombres, se cambian los valores.
   ============================================================ */

/* fonts.css */
/* ============================================================
   fonts.css — tipografías auto-alojadas
   Archivos en /assets/fonts/, subconjunto latino (cubre inglés y
   español: tildes, ñ, ¿ ¡, comillas tipográficas). Variables:
   un archivo cubre todos los pesos. Licencia OFL en fonts/licenses/.
   Origen: Google Fonts, empaquetado por Fontsource.

   Las dos que se ven arriba del pliegue (Fraunces normal y Hanken
   Grotesk normal) se precargan desde site.json → preloadFonts.
   ============================================================ */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-opsz-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-opsz-italic.woff2') format('woff2');
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/hanken-grotesk-latin-wght-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/hanken-grotesk-latin-wght-italic.woff2') format('woff2');
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2');
}

/* site.css */
/* ============================================================
   site.css — estilos del sitio
   Solo usa variables de brand-tokens.css. Las @font-face
   viven en fonts.css, porque cambian con cada cliente.

   Contraste medido (WCAG), y lo que implica:
     · ink sobre paper 13.3:1 · ink-soft 5.05:1 · ember 5.11:1
     · paper sobre ember 5.11:1 → texto de botón en paper
     · ember e ink-soft sobre el degradado amanecer ≈ 4.1:1 → NO
       pasan AA: en .hero el texto y los enlaces van en ink
     · ember sobre ink 2.6:1 → en fondos oscuros, enlaces y
       botones en paper
     · glow 1.44:1 y ember-soft 1.91:1 sobre paper → nunca texto,
       y nunca texto encima de ellos

   Orden: escala de texto · base · tipografía · enlaces y foco ·
          estructura · cabecera · portada · contenido · componentes ·
          pie · movimiento
   ============================================================ */


/* ---------- Escala de texto ----------
   Solo del sitio: por eso vive aquí y no en los tokens de marca,
   que comparten el sitio, las imágenes de los posts y los reportes.
   Fluida: crece con la pantalla entre un mínimo (móvil) y un
   máximo (escritorio). */

:root {
  --text-sm:   0.875rem;                                    /* etiquetas, pie */
  --text-base: clamp(1.0625rem, 1rem + 0.15vw, 1.125rem);   /* cuerpo; nunca por debajo de 16 px */
  --text-lg:   clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem);   /* entradilla, citas */
  --text-h3:   clamp(1.1875rem, 1.1rem + 0.3vw, 1.3125rem);
  --text-h2:   clamp(1.5rem, 1.3rem + 0.8vw, 1.875rem);
  --text-h1:   clamp(2.25rem, 1.7rem + 2.2vw, 3rem);
}


/* ---------- Base ---------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  font-kerning: normal;
  overflow-wrap: break-word;
}

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


/* ---------- Tipografía ---------- */

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  line-height: 1.12;
  color: inherit;
  text-wrap: balance;
}

h1 {
  font-size: var(--text-h1);
  font-weight: 400;
  letter-spacing: -0.02em;
}

h2 {
  font-size: var(--text-h2);
  font-weight: 500;
  letter-spacing: -0.01em;
}

h3 {
  font-size: var(--text-h3);
  font-weight: 600;
}

p,
ul,
ol,
blockquote {
  margin: 0;
}

strong {
  font-weight: 600;
}

.lede {
  font-size: var(--text-lg);
  line-height: 1.5;
  max-width: 52ch;
}

/* Etiquetas en monoespaciada: secciones, metadatos, pequeños rótulos. */
.label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}


/* ---------- Enlaces y foco ---------- */

a {
  color: var(--ember);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 3px solid var(--ember);
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  top: var(--step-1);
  left: var(--step-2);
  z-index: 10;
  padding: var(--step-1) var(--step-2);
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: var(--paper);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}


/* ---------- Estructura ---------- */

.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--step-2);
}

.section {
  padding-block: var(--step-4) var(--step-5);
}

@media (min-width: 48rem) {
  .container {
    padding-inline: var(--step-4);
  }

  .section {
    padding-block: var(--step-5);
  }
}

/* Fondos oscuros: todo el texto y los enlaces pasan a paper. */
.on-ink {
  background: var(--ink);
  color: var(--paper);
}

.on-ink a {
  color: var(--paper);
}

.on-ink :focus-visible {
  outline-color: var(--paper);
}

.on-ink .label {
  color: var(--paper);
}


/* ---------- Cabecera ---------- */

/* Pegada arriba y siempre visible: nunca se esconde al bajar. El fondo es
   opaco para que el contenido pase por debajo sin transparentarse. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid transparent;
  background: var(--paper);
}

/* En cuanto se hace scroll: menos alto, logo más pequeño y un filo fino. */
.site-header.is-scrolled {
  border-bottom-color: var(--mist);
}

.site-header.is-scrolled .site-header__inner {
  padding-block: var(--step-1);
}

.site-header.is-scrolled .site-logo img {
  width: 6rem;
  height: auto;
}

/* Columnas en móvil: logo · (hueco) · reserva · botón de menú.
   El menú ocupa su propia fila. */
.site-header__inner {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: var(--step-1) var(--step-2);
  padding-block: var(--step-2);
}

.site-logo {
  grid-column: 1;
  grid-row: 1;
  justify-self: start;
}

.site-header__cta {
  grid-column: 3;
  grid-row: 1;
}

/* El botón de menú solo existe cuando hay JavaScript: sin él, la navegación
   se queda desplegada y no habría nada que abrir. */
.nav-toggle {
  display: none;
  grid-column: 4;
  grid-row: 1;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--mist);
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.js-nav .nav-toggle {
  display: inline-grid;
}

.nav-toggle svg {
  width: 1.25rem;
  height: 1.25rem;
}

.nav-toggle__close,
.site-header.is-open .nav-toggle__open {
  display: none;
}

.site-header.is-open .nav-toggle__close {
  display: block;
}

/* Sin JavaScript, el menú se ve desplegado, como una fila más. */
.site-menu {
  display: grid;
  gap: var(--step-2);
  grid-column: 1 / -1;
}

.js-nav .site-menu {
  display: none;
}

.js-nav .site-header.is-open .site-menu {
  display: grid;
  padding-block: var(--step-2);
  border-top: 1px solid var(--mist);
}

.lang-switch {
  justify-self: start;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.lang-switch a {
  display: inline-block;
  padding-block: var(--step-1);
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--step-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Dentro del panel, un enlace por línea: se aciertan mejor con el dedo. */
.js-nav .site-header.is-open .site-nav ul {
  display: grid;
  gap: var(--step-1);
}

.site-nav a {
  display: inline-block;
  padding-block: var(--step-1);
  color: var(--ink);
  font-weight: 500;
  white-space: nowrap;
  text-decoration-color: transparent;
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  text-decoration-color: var(--ember);
  text-decoration-thickness: 2px;
}

/* A partir de ~1120 px cabe todo en una línea: el menú deja de ser un panel
   y sus dos partes vuelven a la rejilla de la cabecera. */
@media (min-width: 70rem) {
  .site-header__inner {
    gap: var(--step-3);
  }

  .site-menu,
  .js-nav .site-menu,
  .js-nav .site-header.is-open .site-menu {
    display: contents;
  }

  .js-nav .nav-toggle {
    display: none;
  }

  .site-nav {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .lang-switch {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
  }

  .site-header__cta {
    grid-column: 4;
  }
}

/* Con la cabecera pegada arriba, un destino de ancla necesita aire por
   encima para no quedar debajo de ella (los índices del cambio 29). */
[id] {
  scroll-margin-top: 5.5rem;
}

@media (prefers-reduced-motion: no-preference) {
  .site-header__inner {
    transition: padding 150ms ease;
  }

  .site-logo img {
    transition: width 150ms ease;
  }

  .js-nav .site-header.is-open .site-menu {
    animation: menu-open 150ms ease;
  }
}

@keyframes menu-open {
  from {
    opacity: 0;
    transform: translateY(-0.25rem);
  }
}


/* ---------- Portada: el degradado amanecer ----------
   Solo en portadas (layout home y portadas de sección).
   Encima, solo texto en ink: ember e ink-soft no alcanzan AA. */

.hero {
  padding-block: var(--step-5);
  background-color: var(--paper);
  background-image:
    radial-gradient(ellipse 75% 65% at 100% 0%, var(--wash-mint), transparent 70%),
    radial-gradient(ellipse 65% 75% at 0% 70%, var(--wash-apricot), transparent 70%);
}

.hero .label,
.hero a:not(.button) {
  color: var(--ink);
}

.hero h1 {
  max-width: 18ch;
  margin-top: var(--step-2);
}

/* Ojo al añadir líneas aquí: a 1366x768 al 100 % el botón del hero entra sobre
   el pliegue por 6 px. Una línea más de entradilla lo saca. */
.hero .lede {
  margin-top: var(--step-3);
}

.hero .actions {
  margin-top: var(--step-4);
}

/* En escritorio el hero no necesita una banda alta arriba: la cabecera ya
   ocupa 82 px y el degradado da aire de sobra. Con 6 rem de relleno, el botón
   de reserva caía por debajo del pliegue en pantallas de portátil. El relleno
   de abajo no cambia: es el que separa el hero de la sección siguiente. */
@media (min-width: 48rem) {
  .hero {
    padding-block: var(--step-4) calc(var(--step-5) * 1.25);
  }
}

/* Viewport bajo, sea cual sea el ancho.
 *
 * La regla de arriba pregunta por ANCHO y lo usa como sustituto de "pantalla
 * grande". Un móvil en horizontal rompe ese sustituto: es estrecho Y bajo, cae
 * por debajo de 48rem, y por tanto recibía el relleno GRANDE sobre el viewport
 * MÁS PEQUEÑO de todos. Medido el 22/09/2026 en producción: a 740x300 el hero
 * llevaba 64 px de relleno arriba, y a 1440x774 llevaba 40. Justo al revés de
 * lo que hace falta.
 *
 * 40rem = 640 px, elegido porque el botón del hero termina a 636 px (ver la
 * nota en el front matter de la portada): por debajo de ese alto el relleno ya
 * no está ayudando a nadie. Aquí el relleno de abajo también baja, porque en
 * una pantalla baja el aire de separación cuesta más de lo que aporta.
 *
 * Esto NO pretende meter el botón sobre el pliegue: en un móvil apaisado
 * faltan ~290 px y ningún ajuste de relleno los recupera. No hace falta: la
 * cabecera pegada lleva el mismo botón de reserva, visible a todos los
 * tamaños. Ver docs/pendientes-fase-7.md. */
@media (max-height: 40rem) {
  .hero {
    padding-block: var(--step-4);
  }
}

/* Portada de sección (servicios, cómo trabajamos): banda más corta que la
   de la portada, para que el contenido empiece antes. */
.hero--compact {
  padding-block: var(--step-4);
}

@media (min-width: 48rem) {
  .hero--compact {
    padding-block: var(--step-4);
  }
}

/* Cabecera de páginas de texto: sin degradado, compacta. */
.page-header {
  padding-block: var(--step-4) var(--step-3);
  border-bottom: 1px solid var(--mist);
}

/* Índice de la página, a la derecha del titular. Son enlaces de verdad en
   el HTML. En móvil se oculta: justo debajo viene la misma lista completa,
   así que ahí solo sería repetición. */
.index-card {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-left: 3px solid var(--ember);
  border-radius: var(--radius);
  background: var(--paper);
}

.index-card ol {
  margin: var(--step-2) 0 0;
  padding: 0;
  list-style: none;
}

.index-card li + li {
  margin-top: var(--step-1);
}

.index-card a {
  color: var(--ink);
  text-decoration-color: var(--mist);
}

.index-card a:hover {
  text-decoration-color: var(--ember);
}

@media (max-width: 59.99rem) {
  .index-card {
    display: none;
  }
}


/* ---------- Contenido (Markdown convertido) ---------- */

.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-top: var(--step-2);
}

.prose > h2 {
  margin-top: var(--step-5);
}

.prose > h3 {
  margin-top: var(--step-4);
}

.prose > :first-child {
  margin-top: 0;
}

.prose > h2 + h3 {
  margin-top: var(--step-3);
}

.prose ul,
.prose ol {
  padding-left: var(--step-3);
}

.prose li + li {
  margin-top: var(--step-1);
}

.prose li::marker {
  color: var(--ember);
}

/* El filo terracota marca la cita. */
.prose blockquote {
  padding-left: var(--step-3);
  border-left: 3px solid var(--ember);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-style: italic;
  line-height: 1.45;
}


/* ---------- Componentes ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--step-1) var(--step-3);
  border: 2px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--ember);
  color: var(--paper);
  font-weight: 600;
  line-height: 1.65;
  text-decoration: none;
}

.button:hover {
  background: var(--ink);
}

/* Sobre tinta, el botón terracota no se distingue del fondo (2.6:1):
   se invierte a paper con texto ink. */
.on-ink .button {
  background: var(--paper);
  color: var(--ink);
}

.on-ink .button:hover {
  background: var(--paper-2);
}

/* Panel oscuro de llamada a la acción. */
.panel-ink {
  padding-block: var(--step-5);
}

.panel-ink__inner > * + * {
  margin-top: var(--step-3);
}

.panel-ink h2 {
  max-width: 22ch;
}

.panel-ink p {
  max-width: 52ch;
}

/* Secciones con fondo de caja (paper-2). Contraste: ink 12.1:1,
   ember 4.64:1, ink-soft 4.58:1 — todo pasa AA. */
.section--tint {
  background: var(--paper-2);
}

/* Banda propia para el bloque destacado de propiedad. Va en el tono de
   documento, más claro que el crema del sitio: si usara el de caja se
   fundiría con la banda de los pasos, que está justo encima. Los filos la
   cierran por arriba y por abajo. */
.section--keep {
  border-block: 1px solid var(--mist);
  background: var(--paper-doc);
}

/* Bloque de texto centrado en la página, con ancho contenido. El titular y
   la cita van centrados; los párrafos siguen alineados a la izquierda,
   que es como se leen bien. */
/* Página legal: la columna de texto va centrada en la página, conservando el
   ancho de lectura cómoda de .prose (--measure). El texto de dentro sigue
   alineado a la izquierda: centrar los párrafos haría que cada línea empezara
   en un sitio distinto, que es más difícil de leer, no menos.

   No se usa .prose--centered porque esa además centra los h2 y h3, y aquí el
   encabezado y el texto tienen que leerse como un solo bloque.

   En pantallas estrechas no hace nada: cuando la columna es más angosta que
   --measure, los márgenes automáticos no tienen espacio que repartir. */
.prose--legal {
  margin-inline: auto;
}

.prose--centered {
  max-width: 46rem;
  margin-inline: auto;
}

.prose--centered h2,
.prose--centered h3 {
  text-align: center;
}

.prose--centered blockquote {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

/* Párrafos justificados, con partición de palabras. Solo desde 48rem:
   en la columna estrecha del móvil, el texto justificado deja ríos
   blancos entre palabras. Igual que en las preguntas frecuentes. */
@media (min-width: 48rem) {
  .prose--centered p {
    text-align: justify;
    hyphens: auto;
  }

  .prose--centered blockquote p {
    text-align: left;
  }
}

.section-title {
  margin-bottom: var(--step-4);
}

/* Entradilla justo debajo de un titular. */
h1 + .lede,
h2 + .lede {
  margin-top: var(--step-2);
}

/* Cabecera de Sobre Loden: titular grande con su párrafo de apoyo debajo,
   los dos con el mismo ancho para que el bloque se lea como uno solo. */
/* Cabecera centrada, para páginas con un titular largo de una o dos frases:
   va al tamaño de titular de sección, no al de título de página, y con un
   ancho contenido para que las líneas centradas queden parejas. */
.page-header--centered {
  text-align: center;
}

.page-header--centered h1 {
  max-width: 40ch;
  margin-inline: auto;
  font-size: var(--text-h2);
}

.page-header--centered .lede {
  max-width: 60ch;
  margin-top: var(--step-3);
  margin-inline: auto;
}

.page-header--centered .actions {
  margin-top: var(--step-3);
}

/* "Qué pasa después": cuatro pasos numerados, con el mismo círculo que el
   camino del proceso. En escritorio, una fila compacta; en móvil, apilados
   con el círculo a la izquierda. */
.next-steps {
  display: grid;
  gap: var(--step-4);
  margin: var(--step-4) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: next-step;
}

.next-steps li {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  gap: var(--step-2);
  align-items: start;
  counter-increment: next-step;
}

.next-steps li::before {
  content: counter(next-step, decimal-leading-zero);
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-pill);
  background: var(--ember);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

@media (min-width: 60rem) {
  .next-steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--step-3);
  }

  .next-steps li {
    grid-template-columns: 1fr;
    align-content: start;
  }
}

/* Portada de sección (servicios, cómo trabajamos): mismo degradado, sin etiqueta. */
.hero h1:first-child {
  margin-top: 0;
}

/* Servicios: una columna en móvil, dos en pantallas anchas. */
/* Una fila por servicio, a todo el ancho. Nunca dos servicios uno al lado
   del otro: sus listas tienen largos muy distintos y dejaban huecos. */
.service-list {
  display: grid;
  margin-top: var(--step-4);
}

/* Baldosa del icono: tinta sobre un tono claro. Ni terracota (que en este
   sitio significa "se pulsa") ni menta (solo señales vivas). El icono es
   decoración: va con aria-hidden y sin foco. */
.icon-tile {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-sm);
  background: var(--wash-apricot);
  color: var(--ink);
}

.icon-tile svg {
  width: 1.5rem;
  height: 1.5rem;
}

/* Lista con icono por línea (p. ej. dónde te encuentra la gente). */
.icon-list {
  display: grid;
  gap: var(--step-2);
  margin: var(--step-3) 0;
  padding: 0;
  list-style: none;
}

.icon-list li {
  display: flex;
  align-items: center;
  gap: var(--step-2);
}

.icon-list .icon-tile {
  width: 2rem;
  height: 2rem;
}

.icon-list .icon-tile svg {
  width: 1rem;
  height: 1rem;
}

/* Sobre Loden: ficha a la izquierda, biografía a la derecha.
   En móvil, la ficha va arriba y la biografía debajo. */
.about__grid {
  display: grid;
  gap: var(--step-4);
}

.founder-card {
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-radius: var(--radius);
  background: var(--paper-2);
}

/* Iniciales en lugar de foto: tinta con el texto en crema (13.3:1). */
.founder-card__initials {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: var(--text-h3);
  line-height: 1;
}

.founder-card__name {
  margin-top: var(--step-2);
  font-family: var(--font-display);
  font-size: var(--text-h3);
  line-height: 1.2;
}

.founder-card__facts {
  margin-top: var(--step-1);
  color: var(--ink-soft);
  font-size: var(--text-sm);
}

@media (min-width: 60rem) {
  .about__grid {
    grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
    gap: var(--step-5);
    align-items: start;
  }

  /* La biografía es más larga que la ficha, así que la ficha acompaña. */
  .founder-card {
    position: sticky;
    top: var(--step-3);
  }
}

/* Cada fila va separada por un filo fino. En móvil se apila: primero el
   icono y el nombre, después lo que incluye. */
.service {
  display: grid;
  gap: var(--step-3);
  padding-block: var(--step-4);
  border-top: 1px solid var(--mist);
}

.service:last-child {
  border-bottom: 1px solid var(--mist);
}

/* Izquierda: icono, nombre y el resultado en una línea. */
.service__head {
  display: grid;
  gap: var(--step-2);
  align-content: start;
}

.service__outcome {
  max-width: 34ch;
  color: var(--ink-soft);
}

.service__link {
  margin-top: var(--step-2);
}

/* Lo que incluye: marca de verificación en verde petróleo (7.3:1 sobre
   crema). En terracota parecería que se puede pulsar. */
.checklist {
  display: grid;
  gap: var(--step-1);
  max-width: var(--measure);
  margin: var(--step-2) 0 0;
  padding: 0;
  list-style: none;
}

.checklist li {
  display: grid;
  grid-template-columns: 1rem 1fr;
  gap: var(--step-2);
  align-items: start;
}

.checklist li::before {
  content: "";
  width: 0.5rem;
  height: 0.85rem;
  margin-top: 0.3em;
  border-right: 2px solid var(--petrol);
  border-bottom: 2px solid var(--petrol);
  transform: rotate(45deg);
}

@media (min-width: 60rem) {
  .service {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--step-5);
  }
}

/* Paquetes: tarjetas sobre paper, con filo terracota. Sin sombras. */
.packages {
  display: grid;
  gap: var(--step-3);
  margin-top: var(--step-4);
}

.package {
  display: flex;
  flex-direction: column;
  gap: var(--step-2);
  padding: var(--step-4) var(--step-3);
  border: 1px solid var(--mist);
  border-top: 3px solid var(--ember);
  border-radius: var(--radius);
  background: var(--paper);
}

.package__promise {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-style: italic;
  line-height: 1.3;
}

.package ul {
  margin: 0;
  padding-left: var(--step-3);
}

.package li + li {
  margin-top: var(--step-1);
}

.package li::marker {
  color: var(--ember);
}

/* El enlace se queda abajo aunque las listas tengan distinto largo. */
.package__cta {
  margin-top: auto;
  padding-top: var(--step-1);
  font-weight: 600;
}

@media (min-width: 60rem) {
  .packages {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- El camino del proceso ----------
   Sigue siendo una lista ordenada con texto real: los círculos y las líneas
   son decoración de CSS (bordes y pseudo-elementos), no imágenes ni SVG.
   Círculo terracota con el número en crema (5.11:1). Sin animación.

   Móvil: un solo camino vertical, círculos y línea a la izquierda.
   Escritorio: cuatro columnas y dos filas, las dos de izquierda a derecha;
   la línea baja del paso 4 al 5 por el filo derecho. */

.steps {
  display: grid;
  margin: var(--step-4) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  column-gap: var(--step-2);
  padding-bottom: var(--step-4);
  counter-increment: step;
}

.step::before {
  content: counter(step, decimal-leading-zero);
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-pill);
  background: var(--ember);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* La flecha hacia el paso siguiente. En móvil: línea vertical bajo el
   círculo con la punta hacia abajo. El último paso no lleva flecha: el
   camino termina ahí. */
.step__arrow {
  position: absolute;
  top: 2.25rem;
  bottom: 0.9rem;
  left: calc(1.125rem - 0.5px);
  width: 1px;
  background: var(--mist);
}

/* La punta: un ángulo de dos filos girado 45°. Va en un tono más oscuro
   que la línea, porque es lo que indica la dirección. */
.step__arrow::after {
  content: "";
  position: absolute;
  bottom: -5px;
  left: -4px;
  width: 8px;
  height: 8px;
  border-right: 1px solid var(--ink-soft);
  border-bottom: 1px solid var(--ink-soft);
  transform: rotate(45deg);
}

.step:last-child .step__arrow {
  display: none;
}

/* Solo se usa en el salto de línea del escritorio. */
.step__wrap {
  display: none;
}

.step h3,
.step p {
  grid-column: 2;
}

.step p {
  margin-top: var(--step-1);
}

@media (min-width: 60rem) {
  .steps {
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
  }

  .step {
    grid-template-columns: 1fr;
    /* Sin esto, la celda reparte el alto sobrante entre círculo, título y
       texto, y los pasos de una misma fila no arrancan a la misma altura. */
    align-content: start;
    padding: 0 var(--step-3) var(--step-5) 0;
  }

  /* El círculo abre la celda, en el flujo, y se pinta por encima de la línea. */
  .step::before {
    position: relative;
    z-index: 1;
    grid-row: auto;
    margin-bottom: var(--step-2);
  }

  /* Dentro de una fila: línea horizontal desde el círculo hasta el
     siguiente, con la punta hacia la derecha. La línea se detiene antes del
     borde de la columna: el círculo siguiente empieza justo ahí y, si la
     flecha llegara hasta él, la punta quedaría tapada por debajo. */
  .step__arrow {
    top: 1.125rem;
    right: 0.625rem;
    bottom: auto;
    left: 2.75rem;
    width: auto;
    height: 1px;
  }

  .step__arrow::after {
    top: -4px;
    right: -5px;
    bottom: auto;
    left: auto;
    border-top: 1px solid var(--ink-soft);
    border-right: 1px solid var(--ink-soft);
    border-bottom: 0;
  }

  /* Del paso 4 al 5, como un salto de línea: la línea sale del 04 hacia la
     derecha, baja por el filo de la columna (sin cruzar el texto), corre
     hacia la izquierda por el hueco entre las dos filas y entra en el 05
     desde arriba. Las columnas miden lo mismo, así que 300% son
     exactamente las tres que hay que recorrer hacia la izquierda. */
  .step:nth-child(4) .step__arrow {
    right: 0;
  }

  /* Sin punta al final del tramo: la flecha está abajo, al entrar en el 05. */
  .step:nth-child(4) .step__arrow::after {
    display: none;
  }

  .step:nth-child(4) .step__wrap {
    display: block;
    position: absolute;
    top: 1.125rem;
    right: 0;
    bottom: 2rem;
    left: calc(1.125rem - 300%);
    border-right: 1px solid var(--mist);
    border-bottom: 1px solid var(--mist);
  }

  /* La bajada final hacia el círculo 05. */
  .step:nth-child(4) .step__wrap::before {
    content: "";
    position: absolute;
    top: 100%;
    left: -0.5px;
    width: 1px;
    height: 1.25rem;
    background: var(--mist);
  }

  /* Y su punta, apuntando hacia abajo, justo encima del 05. */
  .step:nth-child(4) .step__wrap::after {
    content: "";
    position: absolute;
    top: calc(100% + 1.25rem - 4px);
    left: -4px;
    width: 8px;
    height: 8px;
    border-right: 1px solid var(--ink-soft);
    border-bottom: 1px solid var(--ink-soft);
    transform: rotate(45deg);
  }

  /* El último paso ocupa dos columnas: así la línea de la segunda fila
     llega hasta el borde y el camino no queda cortado. */
  .step:last-child {
    grid-column: span 2;
  }

  .step h3,
  .step p {
    grid-column: 1;
  }
}

/* Botón de reserva de la cabecera. Por debajo de 480 px se abrevia
   ("Book" / "Agenda"); el nombre accesible sigue siendo el completo.
   La columna la decide el bloque de la cabecera, que cambia según el ancho:
   aquí solo va el aspecto. */
.site-header__cta {
  /* 44 px de alto mínimo: es el tamaño con el que se acierta con el dedo. */
  min-height: 2.75rem;
  padding: var(--step-1) var(--step-2);
  font-size: var(--text-sm);
  white-space: nowrap;
}

/* Si el ancho aprieta, lo que se estrecha es el botón, nunca el logo, y
   antes de que nada llegue a solaparse. */
@media (max-width: 22.5rem) {
  .site-header__cta {
    padding-inline: var(--step-1);
  }
}

.button__short {
  display: none;
}

@media (max-width: 29.99rem) {
  .button__long {
    display: none;
  }

  .button__short {
    display: inline;
  }
}

@media (min-width: 48rem) {
  .site-header__cta {
    padding-inline: var(--step-3);
  }
}

.button--large {
  padding: var(--step-2) var(--step-4);
  font-size: var(--text-lg);
}

/* Portada: texto a la izquierda, tarjeta de frases a la derecha. */
.hero__grid {
  display: grid;
  gap: var(--step-4);
  align-items: center;
}

@media (min-width: 60rem) {
  .hero__grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: var(--step-5);
  }
}

/* Tarjeta de frases. Sin JavaScript, o con movimiento reducido, se ven
   las siete en lista. Con JavaScript, pain-rotator.js añade .is-rotating
   y marca la visible con .is-active. Todas comparten la misma celda: la
   tarjeta toma el alto de la frase más larga y no salta al cambiar. */
/* Centrada en su columna, sin ocupar todo el ancho disponible. */
.pain-card {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-left: 3px solid var(--ember);
  border-radius: var(--radius);
  background: var(--paper);
}

/* Control de pausa: el JavaScript lo muestra al empezar a rotar. Sin
   JavaScript no aparece (no hay nada que pausar) y con movimiento
   reducido tampoco, porque ahí la lista ya es estática. */
.pain-card__toggle {
  margin-top: var(--step-2);
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.pain-card__toggle:hover {
  color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .pain-card__toggle {
    display: none;
  }
}

.pain-list {
  margin: var(--step-2) 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.35;
}

.pain-list li + li {
  margin-top: var(--step-2);
  padding-top: var(--step-2);
  border-top: 1px solid var(--mist);
}

.pain-card.is-rotating .pain-list {
  display: grid;
}

.pain-card.is-rotating .pain-list li {
  grid-area: 1 / 1;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
}

.pain-card.is-rotating .pain-list li.is-active {
  opacity: 1;
}

/* Textos de sección de la portada. */
.section-intro {
  max-width: var(--measure);
  margin-top: var(--step-2);
}

/* Titular e introducción de sección, centrados. El texto largo (tarjetas,
   respuestas) sigue alineado a la izquierda: centrado cuesta leerlo. */
.section-head {
  max-width: 46ch;
  margin-inline: auto;
  text-align: center;
}

.section-head .section-intro {
  margin-inline: auto;
}

/* "Para quién es Loden": aquí todos los bloques son cortos y van centrados. */
.section--center {
  text-align: center;
}

.section--center .who__lead,
.section--center .section-intro {
  margin-inline: auto;
}

.section--center .tags {
  justify-content: center;
}

.who__lead {
  max-width: 34ch;
  margin-top: var(--step-3);
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 500;
  line-height: 1.3;
}

/* Etiquetas (oficios): se escanean de un vistazo. Fondo albaricoque, que da
   color sin parecer un botón (el terracota sólido marca lo que se pulsa).
   Texto en tinta: 10.6:1. */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--step-1);
  margin: var(--step-3) 0;
  padding: 0;
  list-style: none;
}

.tags li {
  padding: calc(var(--step-1) / 2) var(--step-2);
  border-radius: var(--radius-pill);
  background: var(--wash-apricot);
  color: var(--ink);
  font-size: var(--text-sm);
}

/* Tarjetas de servicios de la portada: la tarjeta entera es el enlace.
   Descripción en ink-soft sobre paper-2 (4.58:1, pasa AA). */
.service-cards {
  display: grid;
  gap: var(--step-2);
  margin: var(--step-4) 0 0;
  padding: 0;
  list-style: none;
}

.service-card {
  display: flex;
  flex-direction: column;
  gap: var(--step-1);
  height: 100%;
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-radius: var(--radius);
  background: var(--paper-2);
  color: var(--ink-soft);
  text-decoration: none;
}

.service-card:hover {
  border-color: var(--ember);
}

/* Dentro de la tarjeta el fondo ya es el tono de caja: la baldosa pasa a
   crema para que se distinga. */
.service-card .icon-tile {
  margin-bottom: var(--step-1);
  background: var(--paper);
}

.service-card__title {
  color: var(--ink);
}

/* Indica que la tarjeta lleva a algún sitio. Es parte del mismo enlace,
   no un segundo enlace dentro de la tarjeta. */
.service-card__more {
  margin-top: auto;
  padding-top: var(--step-2);
  color: var(--ember);
  font-size: var(--text-sm);
}

@media (min-width: 48rem) {
  .service-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 60rem) {
  .service-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Preguntas frecuentes: una por fila. La pregunta a la izquierda, la
   respuesta a la derecha, y cada fila mide lo que mide su respuesta.
   En móvil se apilan. Las respuestas siempre visibles, sin acordeón. */
.faq-grid {
  display: grid;
  margin-top: var(--step-4);
  text-align: left;
}

.faq {
  display: grid;
  gap: var(--step-1);
  padding-block: var(--step-3);
  border-top: 1px solid var(--mist);
}

.faq:last-child {
  border-bottom: 1px solid var(--mist);
}

.faq__answer > * + * {
  margin-top: var(--step-2);
}

/* Respuestas justificadas, con partición de palabras para que no se abran
   huecos entre palabras. Solo desde 48rem: en una columna estrecha, el
   texto justificado deja ríos blancos. */
@media (min-width: 48rem) {
  .faq__answer {
    text-align: justify;
    hyphens: auto;
  }
}

@media (min-width: 48rem) {
  .faq {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: var(--step-4);
  }
}

/* Lista de lo que abarca un servicio. */
.service ul {
  margin-top: var(--step-2);
  padding-left: var(--step-3);
}

.service li + li {
  margin-top: var(--step-1);
}

.service li::marker {
  color: var(--ember);
}

@media (prefers-reduced-motion: no-preference) {
  .pain-card.is-rotating .pain-list li {
    transition: opacity 600ms ease;
  }

  .service-card,
  .article-card {
    transition: border-color 150ms ease;
  }
}

/* Señal viva (menta). SOLO para algo que está pasando ahora:
   un estado del sistema, un dato en vivo. Nunca decoración.
   El anillo ink le da contraste sobre paper (el menta solo da 1.44:1). */
.signal {
  display: inline-flex;
  align-items: center;
  gap: var(--step-1);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.signal::before {
  content: "";
  width: 0.625em;
  height: 0.625em;
  border-radius: var(--radius-pill);
  background: var(--glow);
  box-shadow: 0 0 0 1px var(--ink);
}

.plain-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.plain-list li + li {
  margin-top: var(--step-1);
}


/* ---------- Artículos ---------- */

/* Autora y fechas bajo el titular: texto secundario, más pequeño. */
.article__meta {
  margin-top: var(--step-3);
  color: var(--ink-soft);
  font-size: var(--text-sm);
}

.article__meta > * + * {
  margin-top: calc(var(--step-1) / 2);
}

/* Una sola columna de lectura, centrada en la página y con el texto
   alineado a la izquierda. Cuerpo, preguntas, fuentes y aviso comparten el
   mismo ancho para que sus bordes izquierdos coincidan. */
.article__column {
  max-width: var(--measure);
  margin-inline: auto;
}

.article__faq,
.article__sources {
  margin-top: var(--step-5);
}

/* Imagen principal, opcional: a lo ancho de la columna de lectura, encima
   del cuerpo. width y height vienen en el HTML; height: auto (de la base)
   mantiene la proporción. */
.article__image {
  margin: 0 0 var(--step-4);
}

.article__image img {
  width: 100%;
  border-radius: var(--radius);
  background: var(--paper-2);
}

/* El titular del artículo va al tamaño de titular de sección (como en Sobre
   Loden y Contacto). Los h2 del cuerpo bajan un escalón y los h3 otro, para
   que ninguno compita con el titular. */
.article__column h2 {
  font-size: var(--text-h3);
  font-weight: 600;
  line-height: 1.25;
}

.article__column h3 {
  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1.35;
}

.article__column .prose > h2 {
  margin-top: var(--step-4);
}

.article__column .prose > h3 {
  margin-top: var(--step-3);
}

/* Mismo estilo de fila que las preguntas de la portada. En la columna de
   lectura, más estrecha, el hueco se reduce y la respuesta no se justifica:
   a este ancho, justificar abre huecos grandes entre palabras. */
.article__faq .faq-grid {
  margin-top: var(--step-3);
}

@media (min-width: 48rem) {
  .article__faq .faq {
    gap: var(--step-3);
  }

  .article__faq .faq__answer {
    text-align: left;
    hyphens: manual;
  }
}

/* La cita [n] es un enlace a su fuente: discreta, sin romper la línea. */
.cite {
  font-size: 0.85em;
  text-decoration-line: none;
  white-space: nowrap;
}

.cite:hover {
  text-decoration-line: underline;
}

.sources {
  margin: var(--step-3) 0 0;
  padding-left: var(--step-3);
}

.sources li + li {
  margin-top: var(--step-2);
}

.sources li::marker {
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.sources__host {
  display: block;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* Aviso: pequeño y en texto secundario, separado por un filo. */
.article__disclaimer {
  margin-top: var(--step-4);
  padding-top: var(--step-3);
  border-top: 1px solid var(--mist);
  color: var(--ink-soft);
  font-size: var(--text-sm);
}

/* Segundo botón sobre fondo oscuro (llamar, junto al de reserva): contorno
   en crema, para que no compita con el botón sólido. */
.on-ink .button--ghost {
  border-color: var(--paper);
  background: none;
  color: var(--paper);
}

.on-ink .button--ghost:hover {
  background: var(--paper);
  color: var(--ink);
}


/* ---------- Formulario ---------- */

/* ------------------------------------------------------------
   Página de contacto: el formulario a la vista, sin desplazarse
   ------------------------------------------------------------
   Es la página cuyo único propósito es que alguien nos escriba, así que el
   formulario no puede estar al fondo.

   El orden del HTML es: presentación, formulario, resto. Ese es exactamente
   el orden que hace falta en el móvil —titular, una línea, formulario— y de
   ahí viene la mayoría del tráfico local. En pantalla ancha, la rejilla
   recoloca el formulario a la derecha sin tocar el orden del documento, así
   que lo que se lee con un lector de pantalla y lo que se ve coinciden.
   ------------------------------------------------------------ */
.contact-layout {
  display: grid;
  gap: var(--step-4);
}

/* Mismo tamaño de titular que el resto de páginas interiores: al tamaño de
   un h2, para que no compita con el logo de la cabecera. */
.contact-layout__intro h1 {
  font-size: var(--text-h2);
}

.contact-layout__intro .lede {
  margin-top: var(--step-2);
}

.contact-layout__rest > * + * {
  margin-top: var(--step-5);
}

.contact-layout__form .form-block {
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-radius: var(--radius);
  background: var(--paper-2);
}

@media (min-width: 60rem) {
  .contact-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--step-5);
    align-items: start;
  }

  /* Izquierda la explicación, derecha el formulario, y el formulario empieza
     arriba del todo: se ve sin desplazarse. */
  .contact-layout__intro {
    grid-column: 1;
    grid-row: 1;
  }

  .contact-layout__rest {
    grid-column: 1;
    grid-row: 2;
  }

  .contact-layout__form {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  /* "Qué pasa después" se compone en cuatro columnas a partir de 60rem, que
     en media página quedan estrechísimas. Aquí se queda en lista. */
  .contact-layout__rest .next-steps {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--step-4);
  }

  .contact-layout__rest .next-steps li {
    grid-template-columns: 2.25rem 1fr;
  }
}

/* El formulario acompaña al desplazamiento SOLO si cabe entero en la
   pantalla. Un elemento pegajoso más alto que la ventana se clava por arriba
   y esconde su propio botón de enviar: quien va a escribir ve el formulario
   pero no puede enviarlo sin adivinar que hay que desplazarse dentro de algo
   que parece fijo.

   MEDIDO en staging el 21/09/2026, en columna de 488 px: el bloque del
   formulario ocupa **1053 px**, igual en inglés y en español. Con el margen
   de arriba y un respiro abajo hacen falta unos 1110 px de ventana, o sea
   70rem.

   Consecuencia honesta: casi ninguna pantalla llega a ese alto, así que en
   la práctica el formulario NO se queda pegado casi nunca. Es lo correcto:
   más vale que acompañe al desplazamiento normal que dejar el botón de
   enviar fuera de la vista. Si algún día el formulario adelgaza, este umbral
   baja con él.

   El alto del bloque hay que volver a medirlo si se añade o se quita un
   campo. */
@media (min-width: 60rem) and (min-height: 70rem) {
  .contact-layout__form {
    position: sticky;
    top: var(--step-3);
  }
}

.form-block {
  max-width: 46rem;
}

.form {
  margin-top: var(--step-4);
}

.form__field {
  display: grid;
  gap: var(--step-1);
  margin-bottom: var(--step-3);
}

.form__field label {
  font-weight: 500;
}

.form input,
.form select,
.form textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: var(--step-1) var(--step-2);
  border: 1px solid var(--mist);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
}

.form textarea {
  min-height: 8rem;
  resize: vertical;
}

.form input:focus-visible,
.form select:focus-visible,
.form textarea:focus-visible {
  border-color: var(--ember);
}

/* La trampa antispam: un campo que las personas no ven y los robots sí
   rellenan. Sin JavaScript y sin pedirle nada a quien escribe. */
.form__trap {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.form__actions {
  margin-top: var(--step-4);
}

/* La nota de privacidad, debajo del botón de enviar: se lee si se busca, y
   no compite con el botón. */
.form__privacy {
  margin-top: var(--step-1);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

.panel-ink__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--step-2);
}

/* Índice de artículos: la tarjeta entera es el enlace, como las tarjetas
   de servicios de la portada. Descripción en ink-soft sobre paper-2
   (4.58:1, pasa AA). Una columna en móvil, dos desde 48rem. */
.article-cards {
  display: grid;
  gap: var(--step-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.article-card {
  display: flex;
  flex-direction: column;
  gap: var(--step-1);
  height: 100%;
  padding: var(--step-3);
  border: 1px solid var(--mist);
  border-radius: var(--radius);
  background: var(--paper-2);
  color: var(--ink-soft);
  text-decoration: none;
}

.article-card:hover {
  border-color: var(--ember);
}

.article-card__title {
  color: var(--ink);
  font-size: var(--text-h3);
  font-weight: 600;
  line-height: 1.25;
}

.article-card__date {
  margin-top: auto;
  padding-top: var(--step-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

@media (min-width: 48rem) {
  .article-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Filtro por tipo de artículo. Solo existe con 4 artículos o más, y sus
   botones solo se muestran con JavaScript (el atributo hidden lo quita
   article-filter.js). Etiquetas albaricoque como las de oficios; la
   seleccionada, en tinta. */
.article-filter {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--step-1);
  margin-bottom: var(--step-4);
}

.article-filter[hidden] {
  display: none;
}

.article-filter button {
  min-height: 2.75rem;
  padding: 0 var(--step-2);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--wash-apricot);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

.article-filter button:hover {
  border-color: var(--ink);
}

.article-filter button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper);
}


/* ---------- Pie ---------- */

.site-footer {
  padding-block: var(--step-5) var(--step-3);
  border-top: 1px solid var(--petrol);
  font-size: var(--text-sm);
}

.site-footer__grid {
  display: grid;
  gap: var(--step-4);
}

.site-footer__grid .label {
  margin-bottom: var(--step-2);
}

.site-footer__region {
  margin-top: var(--step-2);
}

/* El SVG del logo trae aire por dentro a la izquierda (~7 px a 120 px de
   ancho). Se compensa para que el logo, la ciudad y el aviso legal
   arranquen en la misma línea vertical. */
.site-footer__logo img {
  margin-left: -7px;
}

.site-footer__legal {
  margin-top: var(--step-4);
  padding-top: var(--step-3);
  border-top: 1px solid var(--petrol);
}

@media (min-width: 48rem) {
  .site-footer__grid {
    grid-template-columns: 2fr 1fr 1fr;
  }
}


/* ---------- Movimiento ----------
   Las transiciones y animaciones solo existen si la persona no ha
   pedido reducir el movimiento. La regla final es una red de
   seguridad para cualquier animación que se añada más adelante. */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  a,
  .button {
    transition:
      background-color 150ms ease,
      color 150ms ease,
      text-decoration-color 150ms ease,
      text-decoration-thickness 150ms ease;
  }

  .skip-link {
    transition: transform 150ms ease;
  }

  .signal::before {
    animation: signal-pulse 2.4s ease-in-out infinite;
  }
}

@keyframes signal-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
