/* ============================================================================
   RESET · Fisioterapia & Diagnóstico
   Sistema de diseño "PROTOCOLO", derivado del Manual de Identidad 2026.

   LA IDEA: la web se compone como la ficha de exploración que Joan rellena en
   la primera visita. Rejilla visible, cada dato en su coordenada, cada bloque
   numerado y medido. El lujo no viene de un efecto: viene de que a lo largo de
   doce páginas todo cae exactamente donde tiene que caer, y eso se lee como
   competencia clínica antes de que nadie lea una palabra.

   POR QUÉ ASÍ Y NO CON FOTOS: no hay ni una fotografía de la consulta, y
   generarlas con IA en un centro sanitario sería engañar. Así que el sistema
   está construido para no necesitarlas: trabajan la tipografía, el vacío, la
   rejilla y el canto de 1 px.

   REGLAS NO NEGOCIABLES DEL BRANDBOOK (§4.6, §5.2, §5.4):
   · Solo 3 colores. Todo lo demás son opacidades de esos tres.
   · Soft Bone es la base dominante. Deep Earth se usa con intención.
   · Las ilustraciones son de uso puntual y nunca dominantes.
   · El logo va siempre vertical, monocolor y proporcional.

   REGLAS DEL SISTEMA (si se rompen, deja de leerse como caro):
   · Repartos de columna permitidos: 7+5, 8+4, 2+7+3 y ancho completo. Nunca 6+6.
   · Ningún tamaño de letra entre 1.25rem y 1.8rem. El hueco es deliberado.
   · Dos secciones contiguas nunca comparten altura.
   · Ninguna sombra gris ni negra. Solo las tres tintadas de más abajo.
   ========================================================================== */

@import url('../fonts/outfit-face.css');

/* ---------------------------------------------------------------- tokens */
:root {
  /* Paleta oficial — valores exactos del manual */
  --bone: #FBF8EF;   /* Soft Bone  · base neutra dominante */
  --earth: #443B36;  /* Deep Earth · texto y acento */
  --sand: #C3B49E;   /* Warm Sand  · secundario */

  /* Derivados admitidos: SOLO opacidades de los tres oficiales */
  --earth-80: rgb(68 59 54 / .80);
  --earth-62: rgb(68 59 54 / .62);
  --earth-40: rgb(68 59 54 / .40);
  --earth-18: rgb(68 59 54 / .18);
  --earth-12: rgb(68 59 54 / .12);
  --earth-06: rgb(68 59 54 / .06);
  --sand-45: rgb(195 180 158 / .45);
  --sand-22: rgb(195 180 158 / .22);
  --bone-78: rgb(251 248 239 / .78);
  --bone-60: rgb(251 248 239 / .60);
  --bone-50: rgb(251 248 239 / .50);
  --bone-18: rgb(251 248 239 / .18);

  /* Tipografía. Codec Pro es de pago (Zetafonts) y no está en Google Fonts.
     Outfit es el sustituto más cercano: geométrica, redondeada, con peso
     variable. Al comprar la licencia basta con cambiar esta línea. */
  --font: 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Escala CON HUECO EN EL CENTRO. Entre 1.25rem y 1.8rem no existe ningún
     tamaño y no se puede añadir: ese salto vacío es lo que separa el titular
     del texto sin necesitar color, y es la mitad del efecto "caro". */
  /* El claim del manual tiene ~70 caracteres. La escala se ajusta a la longitud
     del texto, no al revés: a tamaño de cartel se iría a seis líneas y el hero
     mediría dos pantallas. El tamaño de cartel se reserva para .cartel, que
     solo compone claims cortos. */
  --fs-display: clamp(2.4rem, 5.2vw, 4.6rem);
  --fs-h1:      clamp(2.2rem, 5vw, 4.2rem);
  --fs-h2:      clamp(1.8rem, 3.4vw, 2.6rem);
  --fs-h3:      1.25rem;
  --fs-lead:    clamp(1.08rem, 1.4vw, 1.22rem);
  --fs-body:    1.0625rem;   /* 17px: se lee con dolor y con mala luz */
  --fs-sm:      .9375rem;
  --fs-label:   .6875rem;

  --track-display: -.04em;
  --track-h2: -.02em;
  --track-label: .18em;

  /* Ritmo. Unidad de 8 px: la regla graduada de las láminas, los filetes y el
     interlineado del cuerpo caen todos en el mismo múltiplo. */
  --u: 8px;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --gutter-col: clamp(16px, 1.6vw, 28px);
  --maxw: 1320px;
  --measure: 58ch;
  --measure-lead: 52ch;

  /* Tres alturas de sección. Nunca dos contiguas iguales. */
  --sec-s: clamp(3rem, 6vw, 6rem);
  --sec-m: clamp(4.5rem, 10vw, 10rem);
  --sec-l: clamp(6rem, 14vw, 16rem);

  --hdr-h: 84px;   /* alto ocupado por la píldora flotante + su margen */
  /* Separación de la píldora con el borde de la pantalla. La píldora ES el
     .wrap, así que sin esto el gutter era relleno POR DENTRO y la pieza se
     pegaba al canto del móvil. Lo comparten cabecera y panel del menú para que
     los dos cantos caigan en la misma vertical. */
  --hdr-inset: clamp(1rem, 3.5vw, 2.5rem);
  /* Radios. El 3px de antes lo puse yo, no el manual: el brandbook manda en
     color, tipografía y logo, y no dice nada de esto. Un canto de 3px sobre
     superficies grandes se lee como canto duro de plantilla; a 20px la
     superficie parece una pieza física apoyada en el papel. */
  --r: 20px;
  --r-s: 10px;
  --r-pill: 100px;

  /* Cantos y sombras: ninguna gris, ninguna negra, ninguna difusa. Las tres
     salen de los colores oficiales. La sombra gris difusa es la firma visual
     de la web barata. */
  --sh-1: 0 1px 0 var(--bone-60);
  --sh-2: 0 1px 2px rgb(68 59 54 / .08);
  --sh-in: inset 0 1px 2px rgb(68 59 54 / .10);

  --ease: cubic-bezier(.22, .61, .28, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--bone);
  color: var(--earth);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.647;          /* 17 × 1.647 = 28 = 3.5 unidades de 8 px */
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  hanging-punctuation: first last;
}

/* Cuatro pesos con papel asignado. El 600 desaparece del proyecto: con cinco
   pesos la jerarquía se vuelve ambigua y todo se parece a todo.
     300 · display y entradillas    400 · cuerpo
     500 · etiquetas, cifras, h3    700 · titulares y énfasis                 */
h1, h2, h3, h4 {
  margin: 0;
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: var(--track-h2);
  text-wrap: balance;
}
p { margin: 0 0 1.1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

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

.ico {
  display: inline-block;
  width: 1em; height: 1em;
  vertical-align: -.08em;
  flex: none;
}

::selection { background: var(--earth); color: var(--bone); }

:focus-visible {
  outline: 2px solid var(--earth);
  outline-offset: 3px;
  border-radius: 2px;
}
.section--dark :focus-visible, .ftr :focus-visible { outline-color: var(--bone); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--earth); color: var(--bone);
  padding: .75rem 1.25rem; border-radius: 0 0 var(--r) 0;
}
.skip:focus { left: 0; }

/* Cifras tabulares allá donde se comparan números. Una tabla de tarifas con
   cifras proporcionales baila y se lee como una hoja de cálculo mal hecha. */
.rates, .datos, .registro__n, .coord, .rail, .orden__datos dd {
  font-variant-numeric: tabular-nums lining;
}

/* ---------------------------------------------------------------- layout */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* La rejilla maestra. Es el sustrato de todas las familias de sección y lo
   que hace que las doce URLs se sientan el mismo objeto. */
.wrap--grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter-col);
}

.section { padding-block: var(--sec-m); }
.section--s { padding-block: var(--sec-s); }
.section--l { padding-block: var(--sec-l); }

/* Deep Earth con PROFUNDIDAD, no plano.
   Un color liso a pantalla completa se lee como un rectángulo de pintura. Aquí
   el fondo lleva dos halos muy suaves del propio crema (nada fuera de la
   paleta) que le dan una atmósfera y hacen que el bloque parezca un espacio y
   no una plancha. Es la diferencia entre un fondo y un ambiente. */
.section--dark {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(120% 90% at 78% 0%, rgb(251 248 239 / .09), transparent 62%),
    radial-gradient(90% 70% at 8% 100%, rgb(195 180 158 / .10), transparent 58%),
    var(--earth);
  color: var(--bone);
}
.section--sand { background: var(--sand-22); }

/* Frontera entre secciones del mismo fondo: un filete, no un cambio de color.
   Entre fondos distintos el propio cambio ya hace de frontera. */
.section + .section { border-top: 1px solid var(--earth-12); }
.section--dark + .section, .section + .section--dark,
.section--sand + .section, .section + .section--sand { border-top: 0; }

/* Aquí hubo guías verticales de rejilla dibujadas al 6%. Se quitaron: no
   organizaban nada. Caían en el borde de las columnas 3 y 9, pero las familias
   de sección usan repartos 4+8, 7+5 y 8+4, así que las líneas cortaban el
   contenido por sitios arbitrarios en vez de alinearlo. Una línea que no
   coincide con ningún borde real es decoración, y la decoración que finge ser
   sistema se nota. La rejilla ya se percibe por dónde empiezan y acaban los
   bloques. */

/* ---------------------------------------------------------------- tipos */
.display {
  font-size: var(--fs-display);
  font-weight: 300;
  line-height: 1.02;
  letter-spacing: var(--track-display);
  margin: 0 0 1.6rem;
}
/* Énfasis por PESO dentro del mismo titular y la misma familia. Meter una
   serif suelta en un titular sans para "dar interés" es de aficionado. */
.display em { font-style: normal; font-weight: 700; }

.h1 { font-size: var(--fs-h1); }
.h2 { font-size: var(--fs-h2); }
.h3 { font-size: var(--fs-h3); font-weight: 500; line-height: 1.24; letter-spacing: -.01em; }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--earth-80);
  max-width: var(--measure-lead);
  font-weight: 300;   /* Codec Pro Delgada: ligereza y sofisticación (§4.7) */
}
.section--dark .lead { color: var(--bone-78); }

.prose { max-width: var(--measure); }
.prose p { color: var(--earth-80); }
.prose strong { font-weight: 700; color: var(--earth); }
.section--dark .prose p { color: var(--bone-78); }
/* Las listas de las páginas legales y de la 404: mismo gris que el párrafo y
   un poco de aire entre puntos, que son largos. */
.prose li { color: var(--earth-80); }
.prose li + li { margin-top: .4em; }

/* Notas pequeñas: el IVA bajo la tabla de tarifas y el aviso de la foto con el
   rótulo añadido. En --earth-80 y no en --earth-62: a este tamaño el 62 no
   llega al contraste mínimo sobre Soft Bone. */
.rates__nota, .foto__nota {
  margin: .75rem 0 0;
  font-size: var(--fs-sm);
  color: var(--earth-80);
}

.rule { height: 1px; background: var(--earth-12); border: 0; margin: 0; }

/* COORD · la coordenada de apertura. Sustituye al antetítulo repetido encima
   de cada sección: aquí solo aparece en la portada y en aperturas de página. */
.coord {
  display: block;
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--earth-62);
  margin-bottom: 1.75rem;
}
/* En píldora con canto de 1px, no como línea suelta: la etiqueta pasa a ser
   un objeto colocado sobre el papel y no una raya decorativa. */
.coord {
  width: fit-content;
  padding: .45rem .9rem;
  border: 1px solid var(--earth-18);
  border-radius: var(--r-pill);
  box-shadow: var(--sh-1);
}

/* RAIL · la numeración de sección, en el margen de folio y no encima del
   titular. Es lo que sustituye a los 31 antetítulos que había: el mismo dato,
   fuera del camino de lectura. Horizontal, no girado: a 11 px el texto girado
   añade un modo de fallo y no gana nada. */
.rail {
  display: block;
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--earth-40);
  line-height: 1.5;
  margin: 0;
  padding-top: .35em;
}
.section--dark .rail { color: var(--bone-50); }

/* Los raíles que sobreviven van pegados a su titular dentro del bloque, con la
   pleca corta del manual. No son antetítulos: llevan la numeración de sección
   (§ 01, § 02...) y solo existen donde esa numeración significa algo. */
.rail--tit { margin-bottom: 1.25rem; display: flex; align-items: center; gap: .7rem; }
.rail--tit::before {
  content: ""; width: 1.6rem; height: 1px;
  background: currentColor; flex: none; opacity: .6;
}

.sticky { position: sticky; top: calc(var(--hdr-h) + 32px); }
@media (max-width: 900px) { .sticky { position: static; } }

/* CARTEL · la cita de marca a escala de imagen. Exactamente dos usos en toda
   la web, los dos en la portada. Si aparece un tercero, el recurso se gasta y
   deja de significar nada. */
.cartel {
  font-size: clamp(2.6rem, 8vw, 7rem);
  font-weight: 300;
  line-height: 1.02;
  letter-spacing: -.04em;
  max-width: 14ch;
  text-wrap: balance;
  margin: 0;
}
.cartel strong { font-weight: 700; }

/* Subrayado dibujado a mano, no un border-bottom */
.pen { position: relative; white-space: nowrap; }
.pen::after {
  content: "";
  position: absolute;
  left: -.06em; right: -.06em; bottom: -.06em;
  height: .34em;
  background: var(--sand-45);
  z-index: -1;
  border-radius: 2px 6px 3px 5px;
}

/* ---------------------------------------------------------------- botones */
.btn {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  padding: .95rem 1.6rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--earth);
  background: var(--earth);
  color: var(--bone);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;      /* una etiqueta de botón partida en dos líneas está rota */
  cursor: pointer;
  transition: transform .3s var(--ease), background .3s var(--ease), color .3s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn .ico { transition: transform .3s var(--ease); }
.btn:hover .ico { transform: translateX(3px); }
/* Presión al pulsar: el botón se hunde en el papel en vez de saltar. */
.btn:active { transform: translateY(0); box-shadow: var(--sh-in); transition-duration: 90ms; }

.btn--ghost {
  background: transparent;
  color: var(--earth);
  border-color: var(--earth-40);
}
.btn--ghost:hover { border-color: var(--earth); background: var(--sand-22); }

.section--dark .btn { background: var(--bone); color: var(--earth); border-color: var(--bone); }
.section--dark .btn--ghost {
  background: transparent; color: var(--bone); border-color: rgb(251 248 239 / .35);
}
.section--dark .btn--ghost:hover { border-color: var(--bone); background: rgb(251 248 239 / .08); }

.btns { display: flex; flex-wrap: wrap; gap: .8rem; }

.link {
  text-decoration: none;
  font-weight: 500;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size .4s var(--ease-out);
  padding-bottom: 2px;
}
.link:hover { background-size: 100% 1px; }

/* ---------------------------------------------------------------- header
   Píldora flotante, no barra de ancho completo. Una barra pegada al borde
   superior corta la página en dos y se lee como cromo del navegador; una
   píldora despegada flota SOBRE el contenido y hace que la página parezca
   continuar por debajo. Es de las cosas que más separan una web cara de una
   normal, y no toca nada de lo que manda el brandbook. */
.hdr {
  position: sticky; top: 0; z-index: 100;
  padding: .75rem var(--hdr-inset);
  transition: padding .3s var(--ease);
}
.hdr__in {
  display: flex; align-items: center; gap: 2rem;
  min-height: 58px;
  padding: .4rem .5rem .4rem 1.35rem;
  border-radius: var(--r-pill);
  background: rgb(251 248 239 / .78);
  backdrop-filter: saturate(1.5) blur(18px);
  -webkit-backdrop-filter: saturate(1.5) blur(18px);
  border: 1px solid var(--earth-12);
  /* Canto interior claro: el borde de arriba capta luz como una pieza real. */
  box-shadow: inset 0 1px 0 rgb(251 248 239 / .9), 0 6px 24px rgb(68 59 54 / .07);
  transition: box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.hdr[data-scrolled="true"] .hdr__in {
  border-color: var(--earth-18);
  box-shadow: inset 0 1px 0 rgb(251 248 239 / .9), 0 10px 34px rgb(68 59 54 / .12);
}
/* Con el menú abierto la píldora deja de ser translúcida: si no, el titular
   de la página se lee por detrás del logo y del botón de cerrar. */
body[data-nav="open"] .hdr__in {
  background: var(--bone);
  backdrop-filter: none;
}

/* Sin blur disponible, un fondo casi opaco: si no, el texto de la página se
   leería a través de la píldora. */
@supports not (backdrop-filter: blur(1px)) {
  .hdr__in { background: rgb(251 248 239 / .97); }
}
@media (prefers-reduced-transparency: reduce) {
  .hdr__in { background: rgb(251 248 239 / .97); backdrop-filter: none; }
}
.hdr__logo { display: block; flex: none; }
.hdr__logo svg { height: 34px; width: auto; color: var(--earth); }

.nav { margin-left: auto; display: flex; align-items: center; gap: 1.9rem; }
/* Con siete entradas, entre 900 y 1150 px los enlaces se partían en dos y tres
   líneas dentro de la píldora. Aquí no se parten nunca: se juntan. */
.nav a { white-space: nowrap; }
@media (min-width: 901px) and (max-width: 1150px) {
  .nav { gap: clamp(.85rem, 1.7vw, 1.9rem); }
  .nav a { font-size: .875rem; }
  .nav a.btn { padding: .6rem 1rem; }
}
.nav a {
  font-size: var(--fs-sm); font-weight: 400; text-decoration: none;
  color: var(--earth-80); transition: color .25s var(--ease);
  position: relative; padding-block: .35rem;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--earth); }
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--earth);
}
.nav a.btn { color: var(--bone); padding: .68rem 1.25rem; }
.nav a.btn::after { display: none; }
/* Pie del menú (Pedir cita + WhatsApp): solo existe en el panel del móvil. */
.nav__pie { display: none; }

.burger {
  display: none;
  width: 44px; height: 44px; border: 0; background: none; cursor: pointer;
  align-items: center; justify-content: center;
}
.burger span {
  display: block; width: 22px; height: 1.5px; background: var(--earth);
  position: relative; transition: background .2s;
}
.burger span::before, .burger span::after {
  content: ""; position: absolute; left: 0; width: 22px; height: 1.5px;
  background: var(--earth); transition: transform .32s var(--ease);
}
.burger span::before { top: -7px; }
.burger span::after { top: 7px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span::after { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 900px) {
  .burger { display: flex; margin-left: auto; }
  /* El panel ocupa TODA la altura bajo la cabecera, y el alto sobrante se
     reparte entre las entradas (cada enlace crece por igual) en vez de
     acumularse en un socavón encima de "Pedir cita".
     OJO: la cabecera lleva backdrop-filter, y eso la convierte en bloque
     contenedor de sus descendientes position:fixed. Un `bottom: 0` aquí se
     resolvería contra la cabecera (74px), no contra la pantalla. Por eso el
     límite va en unidades de viewport, que sí son absolutas. */
  .nav {
    position: fixed;
    top: var(--hdr-h); left: var(--hdr-inset); right: var(--hdr-inset); bottom: auto;
    height: calc(100vh - var(--hdr-h) - 1rem);
    height: calc(100dvh - var(--hdr-h) - 1rem);
    /* Opaco y sin backdrop-filter A PROPÓSITO. El .nav vive dentro de
       .hdr__in, que ya filtra: eso convierte a la píldora en el backdrop root
       del menú, así que su desenfoque no llega a ver la página y lo único que
       separaba ambas capas era la transparencia. Se leía el texto de debajo. */
    background: var(--bone);
    border: 1px solid var(--earth-12);
    border-radius: var(--r);
    box-shadow: 0 20px 50px rgb(68 59 54 / .14);
    flex-direction: column; align-items: stretch; gap: 0;
    /* Todo el menú tiene que caber sin desplazarse, también con siete entradas
       y en un móvil pequeño: el aire se mide en vh, con un mínimo para que los
       enlaces se sigan pudiendo tocar cómodos. El scroll queda de red, no de
       plan. */
    padding: clamp(.4rem, 1.2vh, 1rem) var(--gutter)
             max(clamp(.85rem, 2.2vh, 2.5rem), env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateY(-101%);
    visibility: hidden;
    transition: transform .45s var(--ease), visibility .45s;
    margin-left: 0;
  }
  .nav[data-open="true"] { transform: translateY(0); visibility: visible; }
  /* Con el menú abierto, la página se apaga un poco: la tarjeta deja de
     flotar sobre un fondo que compite y se lee como una capa. */
  body[data-nav="open"]::after {
    content: "";
    position: fixed; inset: 0;
    background: rgb(68 59 54 / .38);
    z-index: 99;                    /* justo por debajo de la cabecera (100) */
    animation: fundir .3s var(--ease-out) both;
  }
  /* El botón flotante de WhatsApp se aparta: ya hay uno dentro del menú, y
     encima de la tarjeta se veía como un pegote. */
  body[data-nav="open"] .wa { opacity: 0; pointer-events: none; }
  .nav a { opacity: 0; transform: translateY(6px); transition: opacity .3s var(--ease), transform .3s var(--ease); }
  .nav[data-open="true"] a { opacity: 1; transform: none; }
  .nav[data-open="true"] a:nth-child(1) { transition-delay: .10s; }
  .nav[data-open="true"] a:nth-child(2) { transition-delay: .15s; }
  .nav[data-open="true"] a:nth-child(3) { transition-delay: .20s; }
  .nav[data-open="true"] a:nth-child(4) { transition-delay: .25s; }
  .nav[data-open="true"] a:nth-child(5) { transition-delay: .30s; }
  .nav[data-open="true"] a:nth-child(6) { transition-delay: .35s; }
  .nav[data-open="true"] a:nth-child(7) { transition-delay: .40s; }
  @media (prefers-reduced-motion: reduce) {
    .nav a { opacity: 1; transform: none; transition: none; }
  }
  .nav a {
    flex: 1 1 0;
    display: flex; align-items: center;
    min-height: 2.75rem;               /* nunca por debajo del tamaño de dedo */
    padding: clamp(.4rem, 1vh, .8rem) 0;
    border-bottom: 1px solid var(--earth-12);
    font-size: clamp(.97rem, 2.1vh, 1.05rem);
  }
  .nav a[aria-current="page"]::after { display: none; }
  .nav .btn { justify-content: center; }

  /* Pie del panel: Pedir cita y, debajo, WhatsApp, a lo ancho y abajo del
     todo. El botón suelto de la cabecera se esconde porque aquí va dentro
     del pie. */
  .nav > .btn { display: none; }
  .nav__pie { display: block; padding-top: clamp(1rem, 2.6vh, 1.75rem); }
  .nav__btns { display: grid; grid-template-columns: 1fr; gap: clamp(.45rem, 1vh, .6rem); }
  .nav .nav__btns a.btn {
    margin-top: 0; justify-content: center;
    padding: clamp(.62rem, 1.5vh, .95rem) 1rem; font-size: var(--fs-sm);
    border: 1px solid var(--earth);
  }
  .nav .nav__btns a.btn--ghost { background: transparent; color: var(--earth); border-color: var(--earth-40); }
  .nav__wa .wa__glifo { width: 1.2em; height: 1.2em; }
}

/* ================================================================ FAMILIAS
   Seis familias de sección, cada una con su trabajo. Ninguna se repite dos
   veces seguidas y ninguna aparece más veces de las que dice su cupo. Esa
   disciplina es lo que evita el ritmo de plantilla.
   ========================================================================= */

/* --- PLANO · la apertura de la portada. Una sola vez en toda la web. -----
   El aire de arriba es corto a propósito: por encima de unos 6 rem el titular
   flota a media pantalla y se lee como un fallo de maquetación, no como
   espacio. El aire de esta portada va debajo, no encima. */
/* Medido: a 1280x720 el héroe cabía por 3 px y en pantallas más anchas se
   salía por abajo. El aire de arriba baja y el de abajo pasa de --sec-l a
   --sec-m: la apertura tiene que caber entera en la primera pantalla, con los
   botones a la vista sin hacer scroll. */
.plano { padding-block: clamp(1.25rem, 2.4vw, 2.5rem) var(--sec-m); }
/* Ritmo interno más apretado que el general: aquí cada píxel cuenta. */
.plano__txt .lead { margin-top: 1.1rem; }
.plano__txt .btns { margin-top: clamp(1.5rem, 2.4vw, 2.25rem); }
.plano__txt { grid-column: 1 / 9; }
.plano__meta {
  grid-column: 10 / 13;
  align-self: end;
  display: grid;
  gap: calc(var(--u) * 3);
}
@media (max-width: 900px) {
  .plano__txt, .plano__meta { grid-column: 1 / -1; }
  .plano__meta { margin-top: clamp(2.5rem, 7vw, 4rem); }
}

/* Los tres datos de cabecera, compuestos como las mediciones de una ficha:
   etiqueta a la izquierda, valor alineado a la derecha, filete entre medias. */
.datos { margin: 0; border-top: 1px solid var(--earth-12); }
.datos > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: calc(var(--u) * 1.5) 0;
  border-bottom: 1px solid var(--earth-12);
}
.datos dt {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--earth-40);
}
.datos dd { margin: 0; font-size: var(--fs-sm); font-weight: 500; text-align: right; }

/* --- FICHA · el par titular + argumento. Sustituye a los 15 .split. ------
   El reparto pasa de 0.84fr + 1.16fr (casi simétrico, que es lo que hacía que
   todas las secciones se parecieran) a 4 + 8 columnas de la rejilla maestra.
   Se posiciona por orden de hijo y no por clase: el marcado ya distingue el
   bloque de titular del bloque de contenido, y añadir clases solo para el CSS
   sería duplicar una información que ya está. */
.ficha { align-items: start; }
.ficha > *:first-child { grid-column: 1 / 5; }
.ficha > *:nth-child(2) { grid-column: 5 / 13; }
/* Un tercer hijo (el botón que cierra algunas fichas) cae a ancho de la
   columna de contenido, no al margen del titular. */
.ficha > *:nth-child(3) { grid-column: 5 / 13; }

/* --- APERTURA · variante de FICHA para el bloque que abre una página. -----
   Aquí el primer hijo lleva el H1, así que la proporción se INVIERTE: el
   titular se lleva las siete columnas anchas y lo secundario las cuatro
   estrechas. Sin esto, un H1 de cinco palabras metido en cuatro columnas se
   parte en cinco líneas y la página abre rota. */
.apertura > *:first-child { grid-column: 1 / 8; }
.apertura > *:nth-child(2) { grid-column: 9 / 13; align-self: end; }
@media (max-width: 900px) {
  .apertura > *:first-child,
  .apertura > *:nth-child(2) { grid-column: 1 / -1; }
  .apertura > *:nth-child(2) { margin-top: clamp(2rem, 6vw, 3rem); }
}
/* OJO con la especificidad: las reglas de arriba llevan pseudoclase
   (:first-child = 0,2,0) y una media query NO añade especificidad. Si aquí se
   escribiera `.ficha > *` (0,1,0), perdería contra ellas y en móvil las
   columnas no colapsarían: el titular se montaría encima del texto. Por eso el
   selector móvil repite las mismas pseudoclases. */
@media (max-width: 900px) {
  .ficha > *:first-child,
  .ficha > *:nth-child(2),
  .ficha > *:nth-child(3) { grid-column: 1 / -1; }
  .ficha > *:first-child { margin-bottom: 1.5rem; }
  .ficha > .sticky { position: static; }
}

/* --- CUADRO · los servicios. ---------------------------------------------
   Rehecho. La versión anterior tenía tres fallos: la tarjeta grande dejaba un
   vacío enorme entre el texto y el enlace, las tres filas de la derecha se
   apelotonaban arriba mientras la izquierda medía el doble, y el 01 no estaba
   numerado aunque los otros tres sí.

   Ahora el bloque cuenta una jerarquía de verdad: el diagnóstico diferencial
   es LA pieza (fondo Deep Earth, ocupa media rejilla, tipografía de titular) y
   los otros tres son el sistema que cuelga de ella. No son cuatro cosas
   equivalentes, y el diseño ya no finge que lo sean. */
.cuadro { align-items: stretch; }

.cuadro__pral {
  grid-column: 1 / 7;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: clamp(2.5rem, 6vw, 5rem);
  min-height: clamp(19rem, 30vw, 27rem);
  padding: clamp(1.6rem, 2.6vw, 2.4rem);
  border-radius: var(--r);
  color: var(--bone);
  text-decoration: none;
  /* La misma atmósfera que el resto de superficies oscuras del sitio. */
  background:
    radial-gradient(110% 80% at 82% 8%, rgb(251 248 239 / .10), transparent 60%),
    radial-gradient(80% 60% at 0% 100%, rgb(195 180 158 / .12), transparent 55%),
    var(--earth);
  box-shadow: 0 10px 30px rgb(68 59 54 / .10);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.cuadro__pral:hover { transform: translateY(-3px); box-shadow: 0 18px 44px rgb(68 59 54 / .16); }
.cuadro__pral:active { transform: translateY(0); }

.cuadro__cab {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding-bottom: calc(var(--u) * 2);
  border-bottom: 1px solid var(--bone-18);
}
.cuadro__cab .registro__n { color: var(--bone-50); padding: 0; }
.cuadro__et {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--bone-50);
}
.cuadro__pral h3 {
  font-size: clamp(2rem, 3.6vw, 3rem); font-weight: 700;
  letter-spacing: var(--track-h2); margin-bottom: .9rem;
}
.cuadro__pral p { color: var(--bone-78); max-width: 32ch; }
.cuadro__ir {
  display: inline-flex; align-items: center; gap: .6rem;
  margin-top: 1.6rem;
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: 500;
}
.cuadro__pral:hover .cuadro__ir .ico { transform: translateX(4px); }
.cuadro__ir .ico { transition: transform .3s var(--ease); }

/* Las tres filas miden EXACTAMENTE lo mismo. Antes iban con
   align-content:space-between, que reparte el sobrante según lo que ocupa cada
   texto: la de dos líneas quedaba más alta que la de una y el bloque se leía
   desordenado. Con grid-auto-rows:1fr las tres se reparten la altura de la
   tarjeta grande a partes iguales, midan lo que midan por dentro. */
.cuadro__col {
  grid-column: 8 / 13;
  display: grid;
  grid-auto-rows: 1fr;
}
.cuadro__a {
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  gap: 0 1rem;
  align-content: start;          /* el contenido arranca arriba en las tres */
  padding: calc(var(--u) * 2) 1rem;
  margin-inline: -1rem;          /* el tinte respira sin desalinear el texto */
  border-top: 1px solid var(--earth-12);
  border-radius: var(--r-s);
  text-decoration: none;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
.cuadro__a:last-child { border-bottom: 1px solid var(--earth-12); }
.cuadro__a h3, .cuadro__a p { grid-column: 2; }
.cuadro__a p { color: var(--earth-80); font-size: var(--fs-sm); margin: .3rem 0 0; }

/* Hover: UNA sola cosa, y la del propio sistema. El filete superior se dibuja
   entero, que es el mismo gesto que hace el sitio al entrar en pantalla. Nada
   de desplazar el título solo y dejar atrás el número y el texto: eso era lo
   que se veía descosido. */
.cuadro__a:hover, .cuadro__a:focus-visible {
  background: var(--sand-22);
  border-top-color: var(--earth);
}
.cuadro__a:hover .registro__n, .cuadro__a:focus-visible .registro__n { color: var(--earth); }
.cuadro__a:active { box-shadow: var(--sh-in); }
@media (prefers-reduced-motion: reduce) { .cuadro__a { transition: none; } }

@media (max-width: 900px) {
  .cuadro__pral, .cuadro__col { grid-column: 1 / -1; }
  .cuadro__pral { min-height: 0; gap: clamp(2rem, 8vw, 3rem); }
  .cuadro__col { margin-top: 1.5rem; }
}

/* --- REGISTRO · una sola familia para pasos, banderas, tarifas y FAQ. ----
   La cifra cuelga en el margen y las filas van a ancho de rejilla. Un container
   query, no una media query: el mismo componente sirve en banda ancha y en
   columna estrecha sin duplicar CSS. */
.registro {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--earth-12);
  container-type: inline-size;
}
.registro__fila {
  display: grid; grid-template-columns: 1fr; gap: .35rem;
  padding: calc(var(--u) * 3) 0;
  border-bottom: 1px solid var(--earth-12);
}
@container (min-width: 46rem) {
  .registro__fila {
    grid-template-columns: 4rem minmax(0, 20ch) minmax(0, 1fr);
    gap: 0 clamp(1.5rem, 3vw, 3rem);
    align-items: start;
  }
}
.registro__n {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  color: var(--earth-40); padding-top: .55em;
}
.registro__fila h3 { font-size: var(--fs-h3); font-weight: 500; }
.registro__fila p { color: var(--earth-80); margin: 0; max-width: var(--measure); }
.section--dark .registro { border-color: var(--bone-18); }
.section--dark .registro__fila { border-color: var(--bone-18); }
.section--dark .registro__n { color: var(--bone-50); }
.section--dark .registro__fila p { color: var(--bone-78); }

/* Barrido de hover compartido por todo lo pulsable del sistema: la banda de
   Warm Sand entra desde la izquierda y una pleca marca el borde. Sin saltos ni
   inclinaciones: la marca es calma y precisión. */
.barrido { position: relative; isolation: isolate; }
.barrido::before {
  content: ""; position: absolute; inset: 0 -1rem;
  background: var(--sand-22);
  transform: scaleX(0); transform-origin: left;
  transition: transform .24s var(--ease);
  z-index: -1;
}
.barrido::after {
  content: ""; position: absolute; left: -1rem; top: 0; bottom: 0;
  width: 2px; background: var(--earth);
  transform: scaleY(0); transform-origin: top;
  transition: transform .24s var(--ease);
}
a.barrido:hover::before, a.barrido:focus-visible::before { transform: scaleX(1); }
a.barrido:hover::after, a.barrido:focus-visible::after { transform: scaleY(1); }
a.barrido:active { box-shadow: var(--sh-in); }
.section--dark .barrido::before { background: rgb(251 248 239 / .08); }
.section--dark .barrido::after { background: var(--bone); }
@media (prefers-reduced-motion: reduce) {
  .barrido::before, .barrido::after { transition-duration: .01s; }
}

/* --- LÁMINA · las ilustraciones, con marco medido y pie técnico. ---------
   El cupo es de cuatro (FIG. 01 a FIG. 04) más la FIG. 00 del isotipo. La
   regla graduada del borde izquierdo usa el mismo paso de 8 px que el ritmo
   vertical del sitio, así regla, filetes y filas caen en la misma retícula. */
.lamina { margin: 0; }
.lamina__marco {
  position: relative;
  aspect-ratio: 4 / 5;
  display: grid; place-items: center;
  padding: clamp(1.5rem, 4vw, 3rem) clamp(1.5rem, 4vw, 3rem) clamp(1.5rem, 4vw, 3rem) 2.5rem;
  background: var(--sand-22);
  border: 1px solid var(--earth-12);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  overflow: hidden;
}
.lamina__marco::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 14px;
  background:
    repeating-linear-gradient(to bottom, var(--earth-40) 0 1px, transparent 1px 8px)
      left top / 6px 100% no-repeat,
    repeating-linear-gradient(to bottom, var(--earth-40) 0 1px, transparent 1px 40px)
      left top / 14px 100% no-repeat;
}
.lamina img { width: 100%; max-width: 18rem; height: auto; }
/* La lámina del isotipo va sobre Deep Earth, sin regla ni marco de arena: la
   pieza ya trae su propio fondo. */
.lamina--marca .lamina__marco {
  background: none; padding: 0; aspect-ratio: 4 / 5;
  border-color: var(--earth-18);
}
.lamina--marca .lamina__marco::before { display: none; }
.lamina--marca img { max-width: none; height: 100%; object-fit: cover; }

/* --- BANDERAS · las siete causas que se descartan antes de tratar. --------
   Es el contenido más serio del sitio y el que más diferencia a Joan, así que
   tiene familia propia y no comparte la de los pasos de la sesión.

   Va a DOS columnas por una razón concreta: en una sola, siete filas con el
   número en el margen dejaban el texto en una columna de 20 caracteres, que se
   parte cada cuatro palabras, y media pantalla vacía a la derecha. A dos, cada
   descripción tiene una medida legible y el bloque mide la mitad de alto.

   El número impar no se disimula: la última queda sola en su columna y se ve
   que son siete, que es justo lo que se quiere comunicar. */
.banderas__intro { grid-column: 1 / 8; }
/* Debajo del titular, no flotando en la esquina derecha. Un párrafo pequeño
   suelto arriba a la derecha, sin alinearse con nada, es de los patrones que
   más delatan una plantilla: parece colocado para rellenar la columna. */
.banderas__nota {
  margin: 1.2rem 0 0;
  max-width: var(--measure);
  color: var(--earth-62);
  font-size: var(--fs-sm);
}
.banderas {
  grid-column: 1 / -1;
  list-style: none;
  margin: clamp(2.5rem, 6vw, 4.5rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(2rem, 5vw, 4.5rem);
  border-top: 1px solid var(--earth-12);
}
.bandera {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 0 1rem;
  padding: calc(var(--u) * 2.5) 0;
  border-bottom: 1px solid var(--earth-12);
}
.bandera__n {
  font-size: var(--fs-label);
  letter-spacing: var(--track-label);
  color: var(--earth-40);
  padding-top: .5em;
}
.bandera h3 { grid-column: 2; }
.bandera p {
  grid-column: 2;
  margin: .35rem 0 0;
  color: var(--earth-80);
  font-size: var(--fs-sm);
  max-width: 46ch;
}
/* El filete superior solo lo llevan las dos primeras: las demás lo heredan del
   borde inferior de la de arriba, y así no se duplica la línea. */
.bandera:nth-child(-n+2) { border-top: 0; }

.banderas__pie {
  grid-column: 1 / 9;
  margin: clamp(1.8rem, 3.5vw, 2.6rem) 0 0;
  font-size: var(--fs-sm);
  color: var(--earth-62);
}

@media (max-width: 860px) {
  .banderas__intro, .banderas__nota, .banderas, .banderas__pie { grid-column: 1 / -1; }
  .banderas { grid-template-columns: 1fr; }
  .banderas__nota { margin-top: 1.4rem; }
}

.registro__pie {
  margin-top: clamp(1.8rem, 3.5vw, 2.6rem);
  max-width: var(--measure);
  font-size: var(--fs-sm);
  color: var(--earth-62);
}

/* La cita de marca a escala de cartel, con su lámina al lado. */
/* La cita de marca. La ilustración va SUELTA y grande, sin marco ni regla:
   enmarcada y pequeña competía con el cartel y encima dejaba medio bloque
   vacío. Aquí no espera ninguna fotografía, así que no necesita contenedor:
   es la pieza, no un hueco reservado. */
.cita { align-items: center; }
.cita .cartel { grid-column: 1 / 7; }
.cita__ilus {
  grid-column: 7 / 13;
  width: 100%;
  height: auto;
  opacity: .92;
}
@media (max-width: 900px) {
  .cita .cartel, .cita__ilus { grid-column: 1 / -1; }
  .cita__ilus { margin-top: clamp(2rem, 6vw, 3rem); }
}

/* --- BANDA · fotografía a ancho de rejilla. -----------------------------
   Para cuando la imagen tiene algo que decir y no cabe en una columna
   estrecha: encajada en cuatro columnas quedaba pequeña y con un recorte
   forzado. A ancho completo respira, y el texto se reparte debajo en dos
   columnas en vez de amontonarse en una. */
.banda { grid-column: 1 / -1; margin: 0; }
.banda img {
  width: 100%;
  aspect-ratio: 2200 / 940;
  object-fit: cover;
  border-radius: var(--r);
  border: 1px solid var(--earth-12);
  box-shadow: var(--sh-1);
}
.banda__izq { grid-column: 1 / 6; margin-top: clamp(2.5rem, 5vw, 4rem); }
.banda__der { grid-column: 7 / 12; margin-top: clamp(2.5rem, 5vw, 4rem); }
@media (max-width: 900px) {
  .banda__izq, .banda__der { grid-column: 1 / -1; }
  .banda__der { margin-top: clamp(2rem, 6vw, 3rem); }
}

/* --- ÍNDICE · la apertura de las once páginas interiores. --------------- */
.indice__migas { grid-column: 1 / -1; margin-bottom: clamp(2rem, 5vw, 4rem); }
.indice__h { grid-column: 1 / 9; }
.indice__anclas { grid-column: 10 / 13; align-self: end; }
.indice__anclas ol {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--earth-12);
}
.indice__anclas a {
  display: flex; gap: .75rem;
  padding: .7rem 0;
  border-bottom: 1px solid var(--earth-12);
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; text-decoration: none; color: var(--earth-62);
}
.indice__anclas a:hover { color: var(--earth); }
.indice__anclas span { color: var(--earth-40); }
@media (max-width: 900px) {
  .indice__h, .indice__anclas, .indice__migas { grid-column: 1 / -1; }
  .indice__anclas { margin-top: 2.5rem; }
}

/* --- ORDEN DE VISITA · el cierre de las doce páginas. -------------------
   Es el bloque que más veces se ve del sitio. Al llevar teléfono, horario y
   dirección, el dato de contacto queda al pie de todas las páginas sin tener
   que repetir el pie de página. */
/* El bloque de cita y el pie son UNA sola zona de cierre, no dos. Por eso el
   cierre pierde casi todo su aire inferior: el pie continúa justo debajo con el
   mismo fondo, y lo que los separa es un filete a ancho de rejilla, no un
   cambio de bloque. Antes, con los dos en Deep Earth y con su propio padding
   generoso, se leían como dos pies de página seguidos. */
.orden {
  position: relative; overflow: hidden; padding-bottom: var(--sec-s);
  view-timeline: --cierre block;
}
/* LA R QUE SE ESCRIBE. Sustituye al isotipo desenfocado del 18/09/2026: detrás
   del texto, a baja opacidad y borroso, se leía como un logo mal cargado y no
   como atmósfera (Joan preguntó qué hacía ahí). Ahora es la R del isotipo como
   UN trazo continuo (§4.1: "un tratamiento con su inicio y su final") que se
   dibuja al llegar al cierre, con la línea de la marca (§5.1) y la animación
   que el manual prevé para el logo en movimiento (§5.3: "trazo que se dibuja").
   Nítida y con el mismo grosor proporcional que la línea de las manos. */
/* Va como firma ENCIMA de la columna de datos, no detrás: una línea nítida
   cruzando por detrás de "Carrer de Terque" se leía como un tachón (probado).
   Anclada al bloque de datos, sube y baja con él sea cual sea el largo del
   texto de la izquierda; el aire de arriba del bloque ya estaba vacío. */
/* Es parte de la columna, no un absoluto: con un titular corto (el de la
   página de Joan ocupa una línea) había menos hueco y la R se cortaba por
   arriba. Así, si no cabe, el bloque crece en lugar de recortarla. El margen
   negativo la sube hacia el aire de arriba del bloque, que es donde vive. */
.orden__lado { grid-column: 8 / 13; align-self: end; display: flex; flex-direction: column; }
.orden__trazo {
  align-self: flex-end;
  width: clamp(150px, 17vw, 240px); height: auto;
  margin: calc(var(--sec-l) * -.5) 0 clamp(1rem, 2vw, 1.75rem);
  overflow: visible;
  pointer-events: none;
}
.orden__trazo path {
  fill: none;
  stroke: var(--bone);
  stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .34;
}
@supports (animation-timeline: view()) {
  .orden__trazo path {
    /* pathLength="1": el recorrido entero mide 1, sin medirlo con JS. El hueco
       de 2 evita el punto que deja el remate redondo con la línea a cero. */
    stroke-dasharray: 1 2;
    animation: escribir linear both;
    animation-timeline: --cierre;
    /* Se escribe mientras el bloque ENTRA y termina con la R todavía a la
       vista. Con "cover 50%" en pantallas bajas (móvil, portátil pequeño) la
       página se acababa antes y la R se quedaba al 84 % (medido). */
    animation-range: entry 5% entry 60%;
  }
}
@keyframes escribir {
  from { stroke-dashoffset: 1.02; }
  to   { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .orden__trazo path { animation: none; stroke-dasharray: none; }
}

.orden__claim { grid-column: 1 / 7; }
.orden__datos {
  grid-column: 8 / 13;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0 clamp(1.5rem, 3vw, 2.5rem);
  margin: 0; align-self: end;
}
.orden__datos > div { padding: calc(var(--u) * 1.5) 0; border-top: 1px solid var(--bone-18); }
.orden__datos dt {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--bone-50); margin-bottom: .35rem;
}
.orden__datos dd { margin: 0; font-size: var(--fs-sm); font-weight: 500; line-height: 1.5; }
.orden__datos a { text-decoration: none; }
.orden__datos a:hover { text-decoration: underline; }
.orden__lado .orden__datos { grid-column: auto; align-self: auto; }
@media (max-width: 900px) {
  .orden__claim, .orden__lado { grid-column: 1 / -1; }
  .orden__lado { margin-top: clamp(2.5rem, 6vw, 4rem); }
  /* Sin hueco encima de los datos: la firma se va a la esquina superior del
     bloque, en el aire que hay sobre el título, pequeña y sin tocar texto. */
  .orden__trazo {
    position: absolute; top: clamp(1.25rem, 5vw, 2rem); right: 1.25rem;
    width: 92px; margin: 0;
  }
  /* 2,5 rem más de aire arriba para que la firma no roce el titular (con
     "¿Hablamos de lo tuyo?" la cola tocaba el signo de interrogación). */
  .orden { padding-top: calc(var(--sec-l) + 2.5rem); }
  .orden__trazo path { stroke-width: 3.2; opacity: .3; }
}

/* ---------------------------------------------- figura con línea trazada
   Recurso gráfico principal del manual (§5.1): "trazamos una línea ilustrada
   que siluetea y dibuja las manos, sobre una imagen real". Se conserva intacto
   a la espera de la sesión de fotos. */
/* Contenedor de fotografía. Canto redondeado como el resto de superficies del
   sistema y un filete de 1 px: la foto se apoya en el papel, no está pegada. */
.foto { margin: 0; }
.foto img {
  width: 100%;
  border-radius: var(--r);
  border: 1px solid var(--earth-12);
  box-shadow: var(--sh-1);
}

.trace { position: relative; }
.trace img { width: 100%; border-radius: var(--r); filter: saturate(.92) contrast(1.02); }
.trace--marca img { filter: none; }
.trace__line {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none; overflow: visible;
}
.trace__line path {
  fill: none;
  stroke: var(--bone);
  stroke-width: 2.6;
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: var(--len, 1200);
  stroke-dashoffset: var(--len, 1200);
}
.trace.is-in .trace__line path {
  transition: stroke-dashoffset 1.9s var(--ease-out) .25s;
  stroke-dashoffset: 0;
}
@media (prefers-reduced-motion: reduce) {
  .trace__line path { stroke-dashoffset: 0; transition: none; }
}

/* ------------------------------------------------------------- EL SALTO
   El cuadro de la portada: donde duele, de dónde viene, y la línea del manual
   (§5.1) saltando de una columna a la otra. La estructura ES el argumento, así
   que no lleva numeración: esto no es una secuencia de pasos, es una relación
   entre dos sitios. Los pasos numerados son los de la sección siguiente. */
.saltos__intro > .h2 { grid-column: 1 / 7; }
.saltos__intro > .lead { grid-column: 8 / 13; align-self: end; }
@media (max-width: 900px) {
  .saltos__intro > .h2, .saltos__intro > .lead { grid-column: 1 / -1; }
  .saltos__intro > .lead { margin-top: 1.25rem; }
}

/* La fila de abajo: la foto a la izquierda y TODO el texto al lado. Aquí vivía
   el cuadro de los arcos, que Joan quitó el 29/09/2026; lo que quedó (una frase
   grande suelta y, más abajo, la foto con cuatro líneas de texto al lado) dejaba
   dos huecos grandes en la mitad derecha. Juntando los ejemplos y el cierre en
   la misma columna, las dos columnas acaban midiendo casi lo mismo y se apoyan
   en la misma línea de abajo: eso es lo que hace que se lea como una
   composición y no como tres trozos apilados contra el margen izquierdo. */
.saltos__cierre { margin-top: clamp(2.5rem, 5vw, 4rem); align-items: end; }
.saltos__cierre > .foto { grid-column: 1 / 8; }
.saltos__cierre > .saltos__texto { grid-column: 9 / 13; }
.saltos__texto p { color: var(--earth-80); }

/* El claim oficial del manual (§3) no va escondido en negrita dentro de un
   párrafo: se le da su propio escalón de tamaño y un filete encima, que es lo
   que separa el "qué pasa" del "qué hacemos" sin necesidad de otro titular. */
.saltos__claim {
  margin: clamp(1.4rem, 2.4vw, 1.9rem) 0 .55em;
  padding-top: clamp(1.4rem, 2.4vw, 1.9rem);
  border-top: 1px solid var(--earth-12);
  font-size: clamp(1.2rem, 1.7vw, 1.45rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.015em;
  color: var(--earth);
}
@media (max-width: 900px) {
  .saltos__cierre > .foto, .saltos__cierre > .saltos__texto { grid-column: 1 / -1; }
  .saltos__cierre > .saltos__texto { margin-top: 1.75rem; }
}

/* ------------------------------------------------------------------ mapa
   Imagen propia + botón; el mapa de OpenStreetMap se inserta al pulsar. Misma
   caja que las fotos (canto redondeado y filete) para que no parezca un
   pegote de otra web. */
.mapa { margin: 0; }
.mapa__ir {
  display: block; position: relative;
  width: 100%; padding: 0; border: 0; background: none;
  cursor: pointer; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--earth-12); box-shadow: var(--sh-1);
}
/* Recortada en alto: a ancho completo y en 16:9, el mapa se comía la pantalla
   entera y el bloque parecía la portada de otra web. */
.mapa__ir img {
  display: block; width: 100%;
  height: clamp(260px, 42vh, 440px); object-fit: cover;
}
/* Abajo, no en el centro: en el centro tapaba justo la chincheta. */
.mapa__pedir {
  position: absolute; left: 50%; bottom: clamp(1rem, 3vw, 1.75rem); translate: -50% 0;
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .85rem 1.4rem;
  background: var(--earth); color: var(--bone);
  border-radius: 999px;
  font-size: var(--fs-sm); font-weight: 500; white-space: nowrap;
  box-shadow: var(--sh-1);
  transition: scale .25s var(--ease-out);
}
.mapa__ir:hover .mapa__pedir, .mapa__ir:focus-visible .mapa__pedir { scale: 1.04; }
/* El "ábrelo aquí mismo" del pie: es un botón de verdad (carga algo en la
   página), pero se lee como el resto de enlaces del texto. */
.mapa__abrir {
  padding: 0; border: 0; background: none; color: inherit;
  font: inherit; cursor: pointer;
  text-decoration: underline; text-underline-offset: .22em;
}
.mapa__marco {
  display: block; width: 100%; height: clamp(300px, 52vh, 520px); border: 0;
  border-radius: var(--r); box-shadow: var(--sh-1);
}
.mapa__nota { margin-top: .75rem; font-size: var(--fs-sm); color: var(--earth-80); }
@media (max-width: 600px) {
  .mapa__ir img { height: 280px; }
  .mapa__marco { height: 340px; }
  .mapa__pedir { padding: .7rem 1.1rem; }
}

/* ---------------------------------------------------------------- bloques */
/* Ilustraciones sueltas fuera de lámina (§5.2): uso puntual, nunca dominantes. */
.ilus { width: 100%; max-width: 15rem; height: auto; opacity: .9; }
@media (max-width: 480px) { .ilus { max-width: 11rem; } }

/* franja de mensajes de marca en movimiento */
.ticker {
  overflow: hidden;
  border: 1px solid var(--earth-12);
  border-radius: var(--r-pill);
  box-shadow: var(--sh-1);
  margin-inline: var(--gutter);
  padding-block: 1.15rem;
  --dur: 60s;
}
.ticker__track {
  display: flex; gap: 3.5rem; width: max-content;
  animation: slide var(--dur) linear infinite;
}
.ticker span {
  font-size: var(--fs-sm); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--earth-40); white-space: nowrap;
  display: flex; align-items: center; gap: 3.5rem;
}
.ticker span::after {
  content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--sand);
}
/* Al pasar por encima se para: si alguien quiere leer un claim, puede. */
.ticker:hover .ticker__track, .ticker:focus-within .ticker__track { animation-play-state: paused; }
@keyframes slide { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ticker__track { animation: none; } }

/* tabla de tarifas: mismos filetes y mismo ritmo que el registro */
.rates { width: 100%; border-collapse: collapse; }
.rates th, .rates td {
  text-align: left;
  padding: calc(var(--u) * 2) 1rem calc(var(--u) * 2) 0;
  border-bottom: 1px solid var(--earth-12);
}
.rates th {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--earth-40); font-weight: 500;
}
.rates td:last-child, .rates th:last-child { text-align: right; padding-right: 0; }
.rates .price { font-weight: 500; white-space: nowrap; }
.rates .na { color: var(--earth-40); }

/* FAQ nativo */
.faq details { border-bottom: 1px solid var(--earth-12); }
.faq details:first-child { border-top: 1px solid var(--earth-12); }
.faq summary {
  cursor: pointer; list-style: none;
  padding: calc(var(--u) * 2) 2.5rem calc(var(--u) * 2) 0;
  position: relative;
  font-size: var(--fs-h3); font-weight: 500; line-height: 1.3;
  letter-spacing: -.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: .35rem; top: 1.55rem;
  width: 11px; height: 11px;
  border-right: 1.5px solid var(--earth-40);
  border-bottom: 1.5px solid var(--earth-40);
  transform: rotate(45deg);
  transition: transform .3s var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq details p { padding-bottom: 1.5rem; color: var(--earth-80); max-width: var(--measure); }

/* ---------------------------------------------------------------- footer */
.ftr {
  background: var(--earth);
  color: var(--bone);
  padding-block: 0 2rem;
}
.ftr a { color: inherit; text-decoration: none; }
/* Un solo filete a ancho de rejilla marca la costura interna de la zona. */
.ftr__grid {
  row-gap: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--bone-18);
}
.ftr__marca { grid-column: 1 / 5; }
.ftr__col:nth-of-type(1) { grid-column: 6 / 8; }
.ftr__col:nth-of-type(2) { grid-column: 8 / 10; }
.ftr__col:nth-of-type(3) { grid-column: 10 / 13; }
@media (max-width: 860px) {
  .ftr__marca { grid-column: 1 / -1; }
  .ftr__col:nth-of-type(1) { grid-column: 1 / 5; }
  .ftr__col:nth-of-type(2) { grid-column: 5 / 9; }
  .ftr__col:nth-of-type(3) { grid-column: 9 / 13; }
}
@media (max-width: 560px) {
  .ftr__col:nth-of-type(1), .ftr__col:nth-of-type(2), .ftr__col:nth-of-type(3) {
    grid-column: 1 / -1;
  }
}
.ftr__logo svg { height: 62px; width: auto; color: var(--bone); margin-bottom: 1.4rem; }
/* Los títulos de columna del pie son h2 por jerarquía semántica; el tamaño lo
   decide el diseño, y aquí es el de una etiqueta, no el de un titular. */
.ftr__h {
  font-size: var(--fs-label); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--bone-50);
  margin: 0 0 1.1rem; font-weight: 500; line-height: 1.4;
}
.ftr ul { list-style: none; margin: 0; padding: 0; }
.ftr li { margin-bottom: .6rem; }
.ftr li a { font-size: var(--fs-sm); color: var(--bone-78); transition: color .25s; }
.ftr li a:hover { color: var(--bone); }
.ftr__claim { font-size: var(--fs-lead); font-weight: 300; max-width: 24ch; color: var(--bone-78); }
.ftr__bottom {
  grid-column: 1 / -1;
  margin-top: clamp(1.5rem, 3vw, 2.5rem); padding-top: 1.6rem;
  border-top: 1px solid rgb(251 248 239 / .16);
  display: flex; flex-wrap: wrap; gap: 1rem 2rem; justify-content: space-between;
  font-size: .78rem; color: var(--bone-50);
}

/* ======================================================= PÁGINA DE JOAN
   Cuatro composiciones, una por trabajo. Todas salen de la rejilla maestra y
   de los repartos permitidos (7+5, 8+4, ancho completo): no hay ni un tamaño
   de letra, ni un color, ni una sombra nuevos.
   ========================================================================= */

/* PERFIL · apertura. Texto 7 columnas, retrato 5. Relleno superior corto: con
   el de .section el retrato se iba por debajo del pliegue y el botón también. */
.perfil { padding-block: clamp(1.5rem, 3vw, 3rem) clamp(2.5rem, 5vw, 4.5rem); }
.perfil__grid { align-items: center; }
.perfil__txt { grid-column: 1 / 8; }
.perfil__txt .rail { margin-bottom: 1.5rem; }
/* El H1 tiene que caber en DOS líneas con "fisioterapeuta en Terrassa" entera
   en siete columnas (medido: cabe hasta 58,9 px a 1366 de ancho). Al tamaño
   general de H1 partía "Terrassa" sola en una tercera línea. */
.perfil .h1 { font-size: clamp(2.2rem, 4.2vw, 3.5rem); }
.perfil__txt .lead { margin-top: 1.4rem; }
.perfil__txt .btns { margin-top: clamp(1.75rem, 2.6vw, 2.5rem); }
.perfil__foto { grid-column: 8 / 13; }
.perfil__foto img {
  aspect-ratio: 4 / 5;
  max-height: min(76dvh, 760px);
  object-fit: cover;
  object-position: 50% 30%;
}
@media (max-width: 900px) {
  .perfil__txt, .perfil__foto { grid-column: 1 / -1; }
  .perfil__foto { margin-top: clamp(2rem, 7vw, 3rem); }
  .perfil__foto img { max-height: 72dvh; }
}

/* VOZ · lo que dice Joan, a tamaño de titular y en Delgada (§4.7: "titulares
   grandes y elegantes"). El énfasis va por PESO dentro de la misma familia.
   El texto largo cae en la columna de contenido de las fichas (5 a 13), así
   queda alineado con "Formación" dos bloques más abajo. */
/* Relleno propio y más corto que el de .section. Con --sec-l la cita quedaba
   aislada entre dos franjas vacías de casi 330 px cada una (medido a 1366). */
.voz { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.voz__cita { grid-column: 1 / 11; margin: 0; }
.voz__cita blockquote { margin: 0; }
.voz__cita p {
  font-size: var(--fs-display);
  font-weight: 300;
  line-height: 1.06;
  letter-spacing: var(--track-display);
  text-wrap: balance;
  margin: 0;
}
.voz__cita em { font-style: normal; font-weight: 700; }
.voz__cita figcaption {
  display: flex; align-items: center; gap: .7rem;
  margin-top: 1.75rem;
  font-size: var(--fs-sm); font-weight: 500; color: var(--earth-62);
}
.voz__cita figcaption::before {
  content: ""; width: 1.6rem; height: 1px; background: currentColor; opacity: .6;
}
.voz__txt { grid-column: 5 / 13; margin-top: clamp(1.75rem, 3vw, 2.5rem); }
@media (max-width: 900px) {
  .voz__cita, .voz__txt { grid-column: 1 / -1; }
}

/* TRATO · la foto de sus manos, 8 columnas, con la línea del manual; el texto
   en las 4 restantes, apoyado abajo para que cierre a la altura de la mano. */
.trato { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.trato__grid { align-items: end; }
.trato__foto { grid-column: 1 / 9; }
.trato__txt { grid-column: 9 / 13; }
.trato__txt .h2 { margin-bottom: 1.25rem; }
.trato__fuerte {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--earth-18);
  color: var(--earth-80);
}
.trato__fuerte strong { font-weight: 700; color: var(--earth); }
@media (max-width: 900px) {
  .trato__foto, .trato__txt { grid-column: 1 / -1; }
  .trato__txt { margin-top: clamp(2rem, 6vw, 3rem); }
}

/* La línea de las manos (§5.1) en su versión de foto real. Trazo que ESCALA
   con la imagen (sin non-scaling-stroke), como en el manual: es un gesto sobre
   la foto, no un filete de interfaz. Por defecto se ve entera; solo donde hay
   scroll-driven animations se dibuja al entrar, siguiendo la línea de tiempo
   de la propia figura (una <path> de SVG no tiene caja propia para view()). */
.trace--mano { view-timeline: --manos block; }
.trace--mano .trace__line path {
  stroke-width: 18;
  vector-effect: none;
  stroke-dasharray: none;
  stroke-dashoffset: 0;
}
@supports (animation-timeline: view()) {
  .trace--mano .trace__line path {
    stroke-dasharray: var(--len);
    animation: dibujar linear both;
    animation-timeline: --manos;
    /* Terminada cuando la foto llega al centro de la pantalla, que es donde se
       mira. Con "cover 58%" solo se cerraba al tocar el borde superior, y a foto
       entera en pantalla la línea seguía a tres cuartos (medido). */
    animation-range: cover 10% cover 42%;
  }
}
@keyframes dibujar {
  from { stroke-dashoffset: var(--len); }
  to   { stroke-dashoffset: 0; }
}

/* TÍTULOS · la formación, agrupada. Siete títulos en lista seguida se leen
   como un currículum; en tres grupos se lee qué sabe hacer. Un solo filete por
   grupo, no uno por fila. */
/* Aquí el cierre entraba antes (--sec-s) porque, detrás de una lista corta, su
   aire de arriba se leía como una franja oscura vacía. Desde que la R firma
   ese aire ya no está vacío, y con menos altura la R se cortaba: se quitó. */
.titulos { margin: 0; }
.titulos__grupo {
  display: grid;
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  gap: .55rem clamp(1.5rem, 3vw, 3rem);
  padding: calc(var(--u) * 3) 0;
  border-top: 1px solid var(--earth-12);
}
.titulos dt {
  grid-row: 1 / span 3;
  font-size: var(--fs-label); font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--earth-62);
  padding-top: .5em;
}
.titulos dd {
  grid-column: 2;
  margin: 0;
  font-size: var(--fs-lead);
  line-height: 1.45;
  max-width: var(--measure);
}
.titulos__pie {
  margin-top: 1rem;
  padding-top: calc(var(--u) * 2);
  border-top: 1px solid var(--earth-12);
  font-size: var(--fs-sm);
  color: var(--earth-62);
}
@media (max-width: 640px) {
  .titulos__grupo { grid-template-columns: 1fr; }
  .titulos dt { grid-row: auto; margin-bottom: .35rem; }
  .titulos dd { grid-column: 1; }
}
@supports (animation-timeline: view()) {
  .titulos__grupo { position: relative; }
  .titulos__grupo::before {
    content: "";
    position: absolute; left: 0; right: 0; top: -1px;
    height: 1px; background: var(--earth-12);
    transform: scaleX(0); transform-origin: left;
    animation: trazar linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 22%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .trace--mano .trace__line path { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
  .titulos__grupo::before { display: none; }
}

/* =============================================================== MOVIMIENTO
   Intensidad 5 sobre 10, y ni una décima más: esto es un centro sanitario.
   Nada de secuestro de scroll, panorámicas ni cursores. La firma del sitio es
   la CALIBRACIÓN DE LOS FILETES: al entrar en pantalla, las líneas de cada
   fila se trazan de izquierda a derecha. Comunica una cosa concreta, que es el
   sistema montándose delante de ti, y es la traducción literal de "primero
   entender, después tratar".

   Todo con animation-timeline: view(), que muestrea el compositor. Sin
   JavaScript: un IntersectionObserver puede saltarse elementos en un scroll
   rápido y no dispara nunca en documentos ocultos. Donde no haya soporte
   (Safari, Firefox) no se oculta nada y se ve todo.
   ========================================================================= */
@supports (animation-timeline: view()) {
  .registro__fila, .datos > div, .cuadro__a, .indice__anclas a { position: relative; }
  .registro__fila::before, .datos > div::before, .cuadro__a::before {
    content: "";
    position: absolute; left: 0; right: 0; top: -1px;
    height: 1px; background: var(--earth-12);
    transform: scaleX(0); transform-origin: left;
    animation: trazar linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 22%;
  }
  /* El escalonado va en animation-range, no en animation-delay: las líneas de
     tiempo de scroll ignoran los delays. */
  .registro__fila:nth-child(3n+2)::before { animation-range: entry 12% cover 26%; }
  .registro__fila:nth-child(3n)::before   { animation-range: entry 16% cover 30%; }
  .section--dark .registro__fila::before  { background: var(--bone-18); }

  [data-r] {
    animation: rise linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 20%;
  }
  .rail, .registro__n {
    animation: fundir linear both;
    animation-timeline: view();
    animation-range: entry 20% cover 35%;
  }
}
@keyframes trazar { to { transform: scaleX(1); } }
@keyframes fundir { from { opacity: 0; } to { opacity: 1; } }

/* El hero NO espera a ningún observador: entra con una animación por tiempo
   que arranca sola. Así el titular nunca queda en blanco, que es justo lo que
   arruina el LCP. */
/* La entrada de la primera pantalla NO desvanece, solo desliza. Con opacidad 0
   de salida, Chrome no llega a contar el titular como contenido pintado y la
   portada se quedaba SIN métrica de LCP (medido: cero candidatos con la
   animación, titular a 708 ms sin ella). Eso es lo que mira Google para las
   Core Web Vitals, así que el desvanecido sale caro. Deslizar se ve igual de
   bien y el contenido está visible desde el primer fotograma. */
[data-in] { animation: entrar .8s var(--ease-out) both; }
@keyframes entrar {
  from { transform: translateY(18px); }
  to   { transform: none; }
}
[data-in][data-d="1"] { animation-delay: .07s; }
[data-in][data-d="2"] { animation-delay: .15s; }
[data-in][data-d="3"] { animation-delay: .23s; }
@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  [data-r], [data-in], .rail, .registro__n { animation: none; opacity: 1; transform: none; }
  .registro__fila::before, .datos > div::before, .cuadro__a::before {
    animation: none; transform: none;
  }
}

/* ------------------------------------------------------------- WhatsApp
   Botón flotante, escritorio y móvil. Sustituye al teléfono que había en la
   cabecera: un número en lo primero que ves empuja demasiado a alguien que
   todavía está decidiendo. Abajo a la derecha está disponible sin insistir.

   Va en Deep Earth, no en el verde de WhatsApp: el manual cierra la paleta en
   tres colores y el verde sería el único color ajeno de todo el sitio. El
   glifo en monocromo es un uso admitido de la marca.

   En reposo es un círculo. Al pasar por encima o al enfocarlo con el teclado
   se despliega en píldora y aparece la palabra: quien lo ve claro no necesita
   la etiqueta, y quien duda la tiene. */
.wa {
  position: fixed;
  transition: opacity .25s var(--ease);
  right: clamp(1rem, 2.5vw, 2rem);
  bottom: clamp(1rem, 2.5vw, 2rem);
  z-index: 90;                    /* por debajo de la cabecera (100) */
  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 56px;
  padding: 0 16px;
  border-radius: var(--r-pill);
  background: var(--earth);
  color: var(--bone);
  text-decoration: none;
  box-shadow: 0 6px 20px rgb(68 59 54 / .22), inset 0 1px 0 rgb(251 248 239 / .14);
  transition: gap .32s var(--ease), padding .32s var(--ease),
              transform .32s var(--ease), box-shadow .32s var(--ease);
}
.wa__glifo { width: 24px; height: 24px; flex: none; }
/* La etiqueta se colapsa a cero ancho en reposo. No se usa display:none para
   que la transición tenga algo que animar y para que siga leyéndola el lector
   de pantalla si hiciera falta. */
.wa__txt {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-weight: 500;
  transition: max-width .32s var(--ease);
}
.wa:hover, .wa:focus-visible {
  gap: 10px;
  transform: translateY(-2px);
  box-shadow: 0 12px 30px rgb(68 59 54 / .30), inset 0 1px 0 rgb(251 248 239 / .14);
}
.wa:hover .wa__txt, .wa:focus-visible .wa__txt { max-width: 9rem; }
.wa:active { transform: translateY(0); }
.wa:focus-visible { outline: 2px solid var(--earth); outline-offset: 3px; }

/* En móvil no hay hover: el círculo se queda limpio y no roba ancho. */
@media (max-width: 640px) {
  .wa { height: 52px; padding: 0 14px; }
  .wa__txt { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .wa, .wa__txt { transition: none; }
}
@media print { .wa { display: none; } }

/* ---------------------------------------------------------------- utils */
.u-mt { margin-top: clamp(2rem, 4vw, 3.5rem); }
.u-mt-s { margin-top: 1.4rem; }
.u-center { text-align: center; }
.u-narrow { max-width: 760px; }
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ------------------------------------------------------- datos pendientes
   Marca visible para los datos del negocio que aún no tenemos confirmados.
   Nunca se inventan: un teléfono o una dirección falsos rompen la coherencia
   NAP y hacen daño real al posicionamiento local. Deben saltar a la vista
   para que sea imposible publicar sin rellenarlos. */
.pend {
  display: inline-block;
  font-size: .78em;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--earth);
  background: repeating-linear-gradient(
    -45deg, var(--sand-45) 0 7px, transparent 7px 14px);
  border: 1px dashed var(--earth-40);
  border-radius: 2px;
  padding: .12em .5em;
  white-space: nowrap;
}
.section--dark .pend, .ftr .pend {
  color: var(--bone);
  border-color: rgb(251 248 239 / .4);
  background: repeating-linear-gradient(
    -45deg, rgb(251 248 239 / .16) 0 7px, transparent 7px 14px);
}
