/* ===== PALETA: crema de base + caramelo de acento =====
   Todos los tonos salen del logo definitivo, muestreados pixel a pixel:
   caramelo #cca881 (el círculo) · marrón #563a23 (las letras)
   rubio #f2cf9d (el pelo) · tostado #cf9452 (las orejas) */
:root, [data-theme="light"] {
  --bg: #faf4ea;          /* papel crema */
  --bg-2: #f2e7d5;        /* crema de marca */
  --surface: #fffdf9;
  --ink: #3d2b1c;         /* marrón de lectura */
  --muted: #7a6350;
  --primary: #563a23;     /* marrón del logo: títulos y estructura */
  --accent: #8b5a2b;      /* caramelo tostado: botones y acentos */
  --accent-2: #a56a32;
  --caramelo: #cca881;
  --rubio: #f2cf9d;
  --line: rgba(86,58,35,.16);
  --nav-bg: rgba(250,244,234,.9);
  --alt-bg: #3d2a1a;
  --alt-ink: #f7efe2;
  /* .96 y no .82: sobre el marrón plano de .alt (#8b5a2b), el texto al 82 %
     se quedaba en 4,0 a 1, por debajo del 4,5 que pide un texto de lectura
     (auditoría de contraste, 2026-10-12). */
  --alt-muted: rgba(247,239,226,.96);
  --alt-accent: #f2cf9d;  /* rubio sobre fondo oscuro */
  /* El rubio, pero para LETRA PEQUEÑA sobre marrón (cejas, etiquetas, "Leer
     artículo"): el rubio de arriba da 3,5–3,9 a 1 y a 12 px no se lee bien.
     Los titulares caligráficos siguen con --alt-accent: son grandes y les sobra. */
  --alt-accent-texto: #ffefd6;
  /* Fondo de las tarjetas que van DENTRO de una sección marrón (servicios,
     blog). Antes eran un velo blanco al 5 %, que aclaraba el marrón y dejaba el
     texto de dentro en 4,3 a 1. Ahora es un velo oscuro: la tarjeta sigue
     distinguiéndose, pero hundida en vez de levantada, y el texto gana contraste. */
  --alt-tarjeta: rgba(61,42,26,.16);
  --alt-line: rgba(242,207,157,.3);
  --btn-text: #fbf6ee;
  --shadow: 0 20px 46px -26px rgba(86,58,35,.34);
  --sombra-desborde: rgba(61,43,28,.28); /* aviso de scroll horizontal en listas de chips */
  --barra-desplaz: rgba(86,58,35,.22);   /* barra de scroll horizontal, discreta a propósito */
  --pulse: rgba(207,148,82,.4);
  --pulse-0: rgba(207,148,82,0);
  /* Degradados de marca */
  --grad-band: linear-gradient(90deg, #f2cf9d 0%, #cca881 100%);
  --grad-soft: linear-gradient(145deg, #f7e9cf 0%, #f2cf9d 34%, #ddb083 70%, #cca881 100%);
  --grad-mist: linear-gradient(200deg, #fbf3e6 0%, #f5e6cd 55%, #e8d0ae 100%);
  --grad-deep: linear-gradient(152deg, #2b1d11 0%, #563a23 45%, #7a5230 78%, #a56a32 100%);
  /* Manchas de acuarela: cada una es un elipse deformado con ruido, metido
     en la propia imagen para poder usarlo desde ::before / ::after y que
     así TODAS las secciones lleven las suyas sin tocar el HTML. */
  --mancha-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014 0.021' numOctaves='3' seed='11' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='70' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='5'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='130' ry='96' fill='%23cca881' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.017 0.015' numOctaves='3' seed='29' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='62' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='126' ry='100' fill='%23cf9452' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-c: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.024' numOctaves='3' seed='47' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='78' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='4'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='134' ry='94' fill='%23e0b075' filter='url(%23a)'/%3E%3C/svg%3E");
  /* Para las secciones oscuras: tonos claros y cálidos */
  --mancha-d: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.015 0.019' numOctaves='3' seed='13' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='68' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='5'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='128' ry='98' fill='%23f2cf9d' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-e: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011 0.022' numOctaves='3' seed='31' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='74' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='132' ry='96' fill='%23cca881' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-op: .62;      /* opacidad en secciones claras */
  --mancha-op-alt: .26;  /* en las oscuras: baja, para que el texto se lea */
  --grano-opacidad: .09;
  /* Contorno de los titulares. El contorno contrasta con la LETRA, no con el fondo: 
     letras oscuras llevan contorno claro, letras claras llevan contorno oscuro. */
  --marco-titulo: #eddecd;      /* contorno claro para letra oscura (secciones claras) */
  --marco-titulo-alt: #47301d;  /* contorno oscuro para letra clara (secciones oscuras) */
  --alt-flat: #8b5a2b;    /* fondo plano de .alt: antes iba escrito a mano, ahora es tema */
}
[data-theme="dark"] {
  --bg: #1c140d;
  --bg-2: #150f09;
  --surface: #2a1d13;
  --ink: #f4e8d8;
  --muted: #c0a98f;
  --primary: #f4e8d8;
  --accent: #e0a862;
  --accent-2: #f2cf9d;
  --caramelo: #8a6a48;
  --rubio: #c9a273;
  --line: rgba(224,168,98,.24);
  --nav-bg: rgba(28,20,13,.9);
  --alt-bg: #100b06;
  --alt-ink: #f4e8d8;
  --alt-muted: rgba(244,232,216,.78);
  --alt-accent: #f2cf9d;
  --alt-accent-texto: #f2cf9d; /* en oscuro el rubio ya contrasta de sobra */
  --alt-tarjeta: rgba(255,255,255,.05); /* en oscuro se queda el velo claro de siempre */
  --alt-line: rgba(242,207,157,.22);
  --btn-text: #1c140d;
  --shadow: 0 20px 46px -26px rgba(0,0,0,.7);
  --sombra-desborde: rgba(0,0,0,.55);
  --barra-desplaz: rgba(224,168,98,.3);
  --pulse: rgba(224,168,98,.42);
  --pulse-0: rgba(224,168,98,0);
  --grad-band: linear-gradient(90deg, #8a6a48 0%, #5c452c 100%);
  --grad-soft: linear-gradient(145deg, #2f2115 0%, #3d2b1a 38%, #503722 72%, #6b4a2c 100%);
  --grad-mist: linear-gradient(200deg, #1f160e 0%, #251a10 55%, #2e2114 100%);
  --grad-deep: linear-gradient(152deg, #150e07 0%, #2b1d11 45%, #432c19 78%, #5c3d22 100%);
  /* En oscuro las manchas se apagan: mismo dibujo, tonos tostados sin brillo. */
  --mancha-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014 0.021' numOctaves='3' seed='11' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='70' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='5'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='130' ry='96' fill='%236b4a2c' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.017 0.015' numOctaves='3' seed='29' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='62' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='126' ry='100' fill='%23a5763f' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-c: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.024' numOctaves='3' seed='47' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='78' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='4'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='134' ry='94' fill='%238a6a48' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-d: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.015 0.019' numOctaves='3' seed='13' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='68' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='5'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='128' ry='98' fill='%23c9a273' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-e: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Cdefs%3E%3Cfilter id='a' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011 0.022' numOctaves='3' seed='31' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='74' xChannelSelector='R' yChannelSelector='G'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3C/filter%3E%3C/defs%3E%3Cellipse cx='200' cy='150' rx='132' ry='96' fill='%238a6a48' filter='url(%23a)'/%3E%3C/svg%3E");
  --mancha-op: .5;
  --mancha-op-alt: .3;
  --grano-opacidad: .06;
  /* En modo oscuro todos los fondos son oscuros, la letra es clara -> contorno oscuro */
  --marco-titulo: #47301d;
  --marco-titulo-alt: #47301d;
  --alt-flat: #3a2717;    /* mismo papel que .alt pero oscurecido para el tema oscuro */
}

/* ===== Gotas de acuarela =====
   Muchas manchas pequeñas repartidas por toda la sección. Las coloca
   app.js midiendo antes dónde caen los textos y las imágenes, para
   sembrarlas solo en los huecos libres. El CSS pone el aspecto y el
   movimiento; el reparto es lo único que necesita JavaScript. */
.hero, section { position: relative; overflow: hidden; }
.hero > *:not(.capa-gotas),
section > *:not(.capa-gotas) { position: relative; z-index: 1; }

.capa-gotas {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none; overflow: hidden;
}
/* Sin will-change a propósito: hay más de 150 gotas y fijarlo obligaría al
   navegador a mantener una capa por cada una en memoria para siempre. Al
   animar transform ya las promociona solo mientras se mueven. */
.gota {
  position: absolute;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  opacity: var(--op);
}
.gota.g1 { background-image: var(--mancha-a); }
.gota.g2 { background-image: var(--mancha-b); }
.gota.g3 { background-image: var(--mancha-c); }
.alt .gota.g1 { background-image: var(--mancha-d); }
.alt .gota.g2 { background-image: var(--mancha-e); }
.alt .gota.g3 { background-image: var(--mancha-d); }

/* Cada gota lleva su propio recorrido y duración, escritos por el script,
   para que nunca se muevan las dos a la vez ni en la misma dirección. */
@keyframes gotea {
  from { transform: translate3d(0, 0, 0) rotate(0deg); }
  to   { transform: translate3d(var(--dx), var(--dy), 0) rotate(var(--rot)); }
}
@media (prefers-reduced-motion: no-preference) {
  .gota { animation: gotea var(--dur) ease-in-out infinite alternate; animation-delay: var(--del); }
}

/* Grano de papel: fijo, no acompaña al scroll (una textura no se mueve). */
.agua-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.grano {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none; opacity: var(--grano-opacidad);
}
.grano svg { width: 100%; height: 100%; display: block; }

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: clip; }
body {
  font-family: 'Poppins', system-ui, sans-serif;
  color: var(--ink); background: var(--bg); line-height: 1.7; font-weight: 400;
  transition: background .4s ease, color .4s ease;
  /* Referencia para la capa de acuarela, que ocupa toda la altura del documento. */
  position: relative;
  /* Red de seguridad (ui-ux-pro-max audit): el hero tiene elementos que se
     salen a proposito (foto colgante, mascara de desvanecido) y no habia
     tope global de scroll horizontal. */
  overflow-x: clip;
}
h1, h2 { font-family: 'Playfair Display', Georgia, serif; font-weight: 600; line-height: 1.06; letter-spacing: .004em; }

/* ===== Titulares de Impacto (Anton + Yellowtail a dos capas) ===== */
/* .banner-title ES el <h2> (desde el 2026-10-12): dentro van las dos mitades
   de la frase, cada una en su span. Antes el h2 era solo la mitad gruesa y
   Google leia titulos como "SOMOS" o "Y ALGO MAS"; ahora lee la frase entera
   ("Quiénes somos"). Se ve exactamente igual: las tres lineas de abajo le
   quitan al h2 lo que heredaria de la regla "h1, h2" y que antes no tocaba a
   la mitad caligrafica. Las mayusculas las pone .bold-text, no el texto. */
.banner-title {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
  font-size: 1rem; font-weight: 400; letter-spacing: normal;
}
.hero .banner-title {
  margin-bottom: 1.4rem;
}
.section-head .banner-title {
  margin-bottom: clamp(.4rem, 1.2vh, 1rem);
}

.script-text {
  font-family: 'Yellowtail', cursive;
  font-size: clamp(2.2rem, 5vw, 3.8rem);
  line-height: 0.8;
  color: var(--accent);
  transform: rotate(-3deg) translateY(-6px);
  z-index: 2;
  align-self: flex-start; /* Para que no ocupe el 100% del ancho y se pueda mover */
  /* Contorno del color del fondo para "recortar" la letra gruesa que hay debajo */
  -webkit-text-stroke: 0.12em var(--bg);
  paint-order: stroke fill;
  /* Relieve sutil en secciones claras */
  text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.22);
}
.alt .script-text {
  color: var(--alt-accent);          /* Color claro — la letra serigrafiada es la clara */
  -webkit-text-stroke-color: #8b5a2b; /* Mismo marrón del fondo plano → efecto de mordida/recorte */
  text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.32); /* Relieve sutil */
}

.bold-text {
  font-family: 'Anton', sans-serif;
  font-size: clamp(1.8rem, 4vw, 4.4rem);
  line-height: 0.95;
  color: var(--primary);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  white-space: nowrap;
  margin: 0;
  z-index: 1;
  font-weight: 600; /* el que tenia cuando esta mitad era el h2 */
}
.alt .bold-text { color: var(--alt-ink); }
h3, .serif { font-family: 'Playfair Display', Georgia, serif; font-weight: 500; line-height: 1.2; }
em, .em { font-style: italic; }
a { color: inherit; text-decoration: none; }
/* Foco visible para quien navega con teclado (no aparece al usar el raton) */
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.wrap { width: min(1100px, 90%); margin: 0 auto; }
.eyebrow { font-size: .78rem; letter-spacing: .22em; text-transform: uppercase; color: var(--accent); font-weight: 700; }

/* ===== NAV ===== */
/* Escala de z-index nombrada (hallmark audit): mismos valores de siempre,
   ya no sueltos a mano por el CSS. */
:root {
  --z-nav: 50;
  --z-cookie-banner: 80;
  --z-social-float: 200;
}
header { position: sticky; top: 0; z-index: var(--z-nav); background: var(--nav-bg); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); transition: background .4s ease, transform .35s ease; }
/* Se esconde al bajar, vuelve al subir (app.js decide cuándo): libera el
   alto de la barra para el contenido en pantallas bajas, en vez de robarlo
   siempre aunque estés leyendo a media página. */
header.nav-oculto { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  header { transition: background .4s ease; }
}
nav { display: flex; align-items: center; justify-content: space-between; padding: .65rem 0; }
.logo { display: inline-flex; align-items: center; gap: .55rem; font-family: 'Playfair Display', serif; font-size: 1.5rem; font-weight: 600; color: var(--primary); }
.logo .logo-text span { color: var(--accent); }
/* El logo es redondo y lleva las letras dentro: necesita más alto que un
   logotipo horizontal para que "Lu Groom" siga leyéndose en la barra. */
.logo-full { height: 62px; width: auto; display: block; }
@media (max-width: 640px) { .logo-full { height: 48px; } }
.nav-right { display: flex; align-items: center; gap: 1.8rem; }
.nav-links { display: flex; align-items: center; gap: 2rem; font-size: 1.04rem; font-weight: 500; }
.nav-links a { color: var(--primary); transition: color .2s; }
.nav-links a:hover { color: var(--accent); }
.nav-cta { background: var(--accent); color: var(--btn-text) !important; padding: .78rem 1.7rem; border-radius: 999px; font-size: 1rem; font-weight: 700; transition: background .2s, transform .2s; }
.nav-cta:hover { background: var(--accent-2); transform: translateY(-1px); }
.theme-toggle { background: none; border: 1px solid var(--line); color: var(--primary); width: 46px; height: 46px; border-radius: 999px; cursor: pointer; font-size: 1.2rem; display: grid; place-items: center; transition: border-color .2s, transform .3s; }
.theme-toggle:hover { border-color: var(--accent); transform: rotate(20deg); }
.menu-btn { display: none; background: none; border: none; font-size: 1.5rem; color: var(--primary); cursor: pointer; }

/* ===== BOTONES ===== */
.btns { display: flex; gap: 1rem; flex-wrap: wrap; }
.btn { display: inline-block; padding: .8rem 1.6rem; border-radius: 999px; font-weight: 700; font-size: .98rem; transition: all .2s; cursor: pointer; border: 1.5px solid transparent; }
.btn-primary { background: var(--accent); color: var(--btn-text); }
.btn-primary:hover { background: var(--accent-2); transform: translateY(-2px); }
/* Sobre las secciones marrones (.alt) el botón principal se da la vuelta:
   claro sobre oscuro. Con su color normal (--accent, #8b5a2b) tenía EXACTAMENTE
   el mismo marrón que el fondo de la sección y no se distinguía como botón:
   pasaba con «Enviar mensaje» y con «Ver todos los artículos» (auditoría del
   2026-10-12). Crema sobre ese marrón: 5,1 a 1. */
.alt .btn-primary { background: var(--alt-ink); color: #563a23; box-shadow: 0 10px 22px -14px rgba(0,0,0,.6); }
.alt .btn-primary:hover { background: #fffdf9; }
/* Excepción: la caja crema de «cotillea mi Instagram» vive dentro de una
   sección marrón, pero su botón va sobre crema, así que conserva el marrón. */
.alt .galeria-cta .btn-primary { background: var(--accent); color: var(--btn-text); box-shadow: none; }
.alt .galeria-cta .btn-primary:hover { background: var(--accent-2); }
.btn-ghost { border-color: var(--ink); color: var(--ink); font-weight: 500; }
.btn-ghost:hover { background: var(--ink); color: var(--bg); }

/* ===== HERO ===== */
.hero { background: transparent; padding: 3rem 0 3.2rem; position: relative; overflow: hidden; }
/* El hero de inicio ocupa exactamente la pantalla que queda bajo el menu: ni mas, ni menos */
.hero:has(.hero-inicio) {
  --pad-b: 2.6rem;            /* relleno inferior, referencia para anclar la foto */
  --cuelga: 0px;              /* la foto llega justo al borde inferior del hero */
  /* Desvanecido del borde inferior: el corte de la foto se difumina en el fondo.
     OJO: en px desde abajo, no en %. La caja del <img> es mas alta que la foto pintada
     (object-fit: contain deja aire arriba), asi que un % desvaneceria de mas. */
  --fade: 120px;
  --mascara-abajo: linear-gradient(to top,
      transparent 0,
      rgba(0,0,0,.5)  calc(var(--fade) * .42),
      rgba(0,0,0,.88) calc(var(--fade) * .75),
      #000 var(--fade));
  min-height: calc(100svh - var(--nav-h, 69px));
  display: flex; align-items: stretch;  /* stretch: la rejilla ocupa todo el alto, la foto se ancla abajo */
  padding: 2.2rem 0 var(--pad-b);
  overflow: visible;          /* imprescindible: si no, se recortarian las piernas */
  z-index: 2;                 /* la foto pasa por delante de la barra de confianza */
}
.hero::after { content: ''; position: absolute; inset: auto 0 0 0; height: 5px; background: var(--grad-band); }
/* Con variables, no con colores escritos a mano: el modo oscuro se resuelve
   solo y no hacen falta las cuatro reglas de [data-theme="dark"] que había. */
.hero .eyebrow { display: block; margin-bottom: 1.2rem; color: var(--accent); }
/* max-width: none a propósito. Antes estaba limitado a 15 caracteres y el
   título salía a 279 px mientras el párrafo de debajo medía 462: parecían
   dos bloques distintos. Ahora ocupan lo mismo. */
/* El título ya no necesita ajustes aquí, lo manejan .bold-text y .script-text */
.hero p { font-size: 1.15rem; color: var(--ink); max-width: 52ch; margin-bottom: 2rem; }
.hero .hero-trust { color: var(--muted); }
.firma { margin-top: 3.5rem; }
.firma svg { width: 100%; max-width: 520px; height: auto; }
.firma .teeth line { stroke: var(--accent); }
.firma .growth { stroke: var(--primary); }
.firma .dot { fill: var(--accent); }

/* ===== SECCIONES ===== */
/* ===== Aire vertical, atado a la altura de la pantalla =====
   El objetivo original era que cada sección quepa entera sin deslizar. En
   pantallas normales/altas eso comprimía el aire de más (hallmark audit,
   2026-08-03): se sube el suelo y el techo del clamp para que respire en
   monitores estándar; las reglas de pantallas bajas (@media max-height:860px
   más abajo) se quedan igual y siguen apretando solo cuando hace falta. */
section { padding: clamp(2.5rem, 7vh, 7.5rem) 0; }
/* El header es sticky: sin esto, saltar a un ancla del nav (o a un CTA
   interno tipo #contacto) deja el titulo de la seccion tapado detras de
   la barra (ui-ux-pro-max audit). */
section, .hero { scroll-margin-top: calc(var(--nav-h, 69px) + 1rem); }
.section-head {
  max-width: 60ch;
  margin: 0 auto clamp(1.75rem, 4vh, 4rem);
  text-align: center;
}
.section-head .banner-title { align-items: center; }
/* translateY POSITIVO: la cursiva baja y se monta sobre las mayúsculas, que
   es lo que hace que el efecto de mordida se vea. Valor ajustado por Lucía
   en el inspector del navegador (2026-08-02). */
.section-head .banner-title .script-text {
  align-self: center;
  transform: rotate(-3deg) translateY(6px) translateX(-15px);
}
.section-head .eyebrow { display: block; margin-bottom: clamp(.35rem, 1vh, .8rem); }
/* El titular también se mide contra el alto: en pantallas bajas un titular
   de 58 px se come casi la mitad del espacio útil de la sección. */
/* Titulares delegados a .banner-title */
.section-head p { color: var(--muted); font-size: 1.08rem; }

/* Las secciones .alt pasan de degradado a marrón plano.
   El truco visual: el borde (text-stroke) de .script-text usa ESTE mismo color,
   así la letra cursiva parece recortada sobre las mayúsculas de debajo. */
.alt { background: var(--alt-flat); }
.alt .eyebrow { color: var(--alt-accent-texto); }
.alt h2, .alt h3 { color: var(--alt-ink); }
.alt .section-head p, .alt p { color: var(--alt-muted); }

/* Secciones claras: transparentes a propósito, para que se vean las manchas
   de acuarela del fondo. Si aquí se pinta un degradado, tapa la acuarela y
   la web vuelve a parecer un degradado liso. */
section:not(.alt) { background: transparent; }
/* Líneas doradas y subrayados se quitan porque la fuente Anton ya es masiva */

/* QUIÉNES SOMOS — Lucía y Benji a partes iguales. Línea vertical en ancho,
   horizontal en estrecho: es la misma rejilla de 3 columnas (col/línea/col)
   en los dos casos, el punto de corte de abajo solo la aplana a 1 columna,
   así que la línea del medio queda arriba/abajo sin tocar el orden del DOM. */
.quienes-grid { display: grid; grid-template-columns: 1fr 1px 1fr; align-items: stretch; gap: clamp(1.5rem, 4vw, 3rem) 0; max-width: 900px; margin: 0 auto; }
.quienes-seam { background: linear-gradient(var(--bg), var(--accent-2) 14%, var(--accent-2) 86%, var(--bg)); }
.quienes-col { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 clamp(.5rem, 3vw, 1.6rem); }
.quienes-col p { color: var(--muted); margin-bottom: .8rem; }
.quienes-col .lead { font-family: 'Playfair Display', serif; font-style: italic; font-weight: 600; font-size: 1.14rem; color: var(--primary); line-height: 1.42; margin-bottom: .7rem; }

/* La burbuja: mismo trazo orgánico que .tw-retrato en "Mis trabajos". */
.quienes-burbuja { position: relative; overflow: hidden; width: clamp(180px, 22vw, 260px); aspect-ratio: 4 / 3.8; border-radius: 46% 54% 40% 60% / 34% 32% 68% 66%; background: var(--bg-2); transition: border-radius .6s ease; }
.quienes-col:hover .quienes-burbuja { border-radius: 34% 66% 52% 48% / 44% 40% 60% 56%; }
.quienes-burbuja img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (prefers-reduced-motion: reduce) { .quienes-burbuja { transition: none; } }

/* Sin placa de color debajo (Lucía, 2026-08-10: "quitar el background de la
   tarjeta") — la burbuja y el nombre quedan sueltos sobre el fondo de la
   sección. Se queda como agrupador flex, ya sin fondo ni relleno propio. */
.quienes-placa { display: flex; flex-direction: column; align-items: center; margin-bottom: 1.1rem; }

/* El nombre pide el mismo tratamiento que .script-text de los títulos:
   Yellowtail a un tamaño grande, con el mismo contorno del color de fondo
   para despegarlo de lo que tiene detrás. La sombra NO puede ser
   `text-shadow`: combinada con `-webkit-text-stroke` se pinta por delante
   del contorno y lo ensucia (esto es lo que Lucía vio mal en sus pruebas).
   `filter: drop-shadow()` sombrea la silueta ya compuesta (relleno +
   contorno) como una sola forma, así que cae detrás limpiamente. */
.quienes-nombre {
  font-family: 'Yellowtail', cursive;
  font-size: clamp(1.9rem, 4.2vw, 2.6rem);
  line-height: 0.9;
  color: var(--accent);
  margin-top: 1rem;
  -webkit-text-stroke: 0.06em var(--bg);
  paint-order: stroke fill;
  filter: drop-shadow(1px 1px 4px rgba(0,0,0,.22));
}

.quienes-link { color: var(--accent); font-weight: 700; }
.quienes-link::after { content: ' →'; }
.quienes-link:hover { color: var(--primary); }

@media (max-width: 820px) {
  .quienes-grid { grid-template-columns: 1fr; }
  .quienes-seam { width: 60%; height: 1px; margin: 0 auto; justify-self: center; background: linear-gradient(90deg, var(--bg), var(--accent-2) 14%, var(--accent-2) 86%, var(--bg)); }
}

/* SERVICIOS */
.servicios-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
.card { background: var(--alt-tarjeta); border: 1px solid var(--alt-line); border-radius: 22px; padding: 2.2rem; }
.card h3 { font-size: 1.5rem; margin-bottom: .4rem; }
.card .tag { font-size: .75rem; letter-spacing: .15em; text-transform: uppercase; color: var(--alt-accent-texto); font-weight: 700; }
.card ul { list-style: none; margin-top: 1.3rem; }
.card li { padding: .5rem 0 .5rem 1.6rem; position: relative; border-top: 1px solid var(--alt-line); color: var(--alt-muted); }
.card li:first-child { border-top: none; }
.card li::before { content: '—'; position: absolute; left: 0; color: var(--alt-accent); }

/* PORTFOLIO — un único caso destacado */
.caso { display: grid; grid-template-columns: 1.1fr 1fr; gap: 0; border: 1px solid var(--line); border-radius: 26px; overflow: hidden; background: var(--surface); box-shadow: var(--shadow); }
.caso-info { padding: 2.6rem; }
.caso-info .tag { font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.caso-info h3 { font-size: 2rem; color: var(--primary); margin: .5rem 0 .1rem; }
.caso-info .loc { color: var(--muted); font-size: .9rem; margin-bottom: 1.2rem; }
.caso-info p { color: var(--muted); margin-bottom: 1.4rem; }
.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip { font-size: .8rem; padding: .35rem .9rem; border-radius: 999px; border: 1px solid var(--line); color: var(--ink); }
.caso-foto { background: linear-gradient(160deg, var(--bg-2), var(--bg)); display: flex; align-items: center; justify-content: center; text-align: center; color: var(--muted); font-size: .9rem; padding: 2rem; border-left: 1px solid var(--line); }
.porto-more { text-align: center; margin-top: 2rem; color: var(--accent); font-weight: 600; letter-spacing: .04em; }
.digital-iconos { display: flex; justify-content: center; gap: 2.6rem; flex-wrap: wrap; color: var(--primary); margin: 0 auto 2.4rem; }
.digital-ic { display: flex; flex-direction: column; align-items: center; gap: .55rem; }
.digital-ic svg { width: 40px; height: 40px; }
.digital-ic span { font-family: 'Poppins', sans-serif; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.digital-texto { max-width: 62ch; margin: 0 auto; text-align: center; }
.digital-texto p { color: var(--muted); font-size: 1.08rem; margin-bottom: 1.6rem; }

/* BLOG */
.blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.8rem; }
.post { background: var(--alt-tarjeta); border-radius: 22px; padding: 1.8rem; border: 1px solid var(--alt-line); display: flex; flex-direction: column; transition: transform .2s, border-color .2s; }
.post.linked:hover { transform: translateY(-4px); border-color: var(--alt-accent); }
.post .cat { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--alt-accent-texto); font-weight: 700; }
.post h3 { font-size: 1.2rem; color: var(--alt-ink); margin: .6rem 0; }
.post p { color: var(--alt-muted); font-size: .95rem; flex-grow: 1; }
.soon { display: inline-block; margin-top: 1rem; font-size: .8rem; color: var(--alt-accent); font-weight: 700; }
.read-link { display: inline-block; margin-top: 1rem; font-size: .85rem; color: var(--alt-accent-texto); font-weight: 700; letter-spacing: .02em; }
.read-link::after { content: ' →'; }
/* La puerta al blog completo: en la portada solo se ven tres artículos
   (la rejilla es de tres columnas), el resto está en /blog. */
.blog-mas { text-align: center; margin-top: clamp(1.6rem, 4vh, 2.8rem); }

/* CONTACTO */
#contacto { position: relative; overflow: hidden; }
.contacto-grid { position: relative; z-index: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: start; }

/* Benji asomando en la esquina inferior derecha de Contacto — sin degradado,
   no hace falta: el SVG ya tiene el fondo limpio. Es un dibujo, no un corte
   fotográfico, así que en vez de difuminar un borde, lo que hay que resolver
   es que el LIENZO del SVG (512×512) no es lo mismo que el DIBUJO real:
   Benji deja 46px transparentes bajo las patas dentro de ese cuadrado
   (medido pixel a pixel, no a ojo). Sin corregirlo, "bottom:0" pondría el
   borde del lienzo en la línea de la sección, no sus patas. El translateY
   en % se resuelve contra la ALTURA PROPIA del elemento (spec CSS), así que
   46/512 = 8.988...% desplaza sus patas al pixel exacto sea cual sea el
   tamaño final — no es un valor fijo en px que se desajuste si cambia el
   tamaño. El borde derecho respeta el hueco de las burbujas fijas de
   WhatsApp/Instagram/correo. Oculta en móvil: ahí no queda hueco debajo. */
/* #contacto > .contacto-foto (no solo .contacto-foto): tiene que ganarle en
   especificidad a "section > *:not(.capa-gotas)" de la regla general de arriba,
   que fuerza position:relative a todo hijo directo de una sección para que
   quede por encima de las manchas de acuarela. */
#contacto > .contacto-foto {
  position: absolute;
  z-index: 0;
  /* +70px extra: sin eso, el borde queda a 1px de las burbujas fijas de
     WhatsApp/Instagram/correo (54px de ancho, fixed a 22px del borde). */
  right: calc(clamp(1.2rem, 6vw, 5.5rem) + 70px);
  /* -1px: el translateY de abajo deja las patas a 1px de la línea por
     redondeo de subpíxel del navegador; este ajuste cierra ese resto,
     encontrado por Lucía en devtools. */
  bottom: -1px;
  width: min(24%, 320px); /* tamaño final elegido por Lucía en devtools */
  aspect-ratio: 1 / 1;
  object-fit: contain;
  transform: translateY(8.98828125%); /* 46 / 512, ver nota arriba */
  pointer-events: none;
}
@media (max-width: 900px) {
  #contacto > .contacto-foto { display: none; }
}
.form-field { margin-bottom: 1.2rem; }
.form-field label { display: block; font-size: .85rem; font-weight: 500; margin-bottom: .4rem; color: var(--alt-ink); }
.form-field input, .form-field textarea { width: 100%; padding: .8rem 1rem; border-radius: 14px; border: 1px solid var(--alt-line); background: rgba(255,255,255,.06); color: var(--alt-ink); font-family: inherit; font-size: .95rem; }
.form-field input::placeholder, .form-field textarea::placeholder { color: var(--alt-muted); }
.contacto-info p { margin-bottom: 1rem; color: var(--alt-muted); }
.contacto-info strong { color: var(--alt-ink); }
.channel-btns { display: flex; flex-direction: column; gap: .8rem; margin-bottom: 1.6rem; }
.channel-btn { display: inline-flex; align-items: center; gap: .7rem; padding: .8rem 1.3rem; border-radius: 999px; font-weight: 700; font-size: .95rem; transition: transform .2s, background .2s; }
.channel-btn svg { width: 20px; height: 20px; flex-shrink: 0; }
.channel-btn.wa { background: var(--accent); color: var(--btn-text); }
.channel-btn.wa:hover { background: var(--accent-2); transform: translateY(-2px); }
.channel-btn.ig { border: 1.5px solid var(--alt-line); color: var(--alt-ink); }
.channel-btn.ig:hover { border-color: var(--alt-accent); transform: translateY(-2px); }
.form-status { margin-top: 1rem; padding: .9rem 1.1rem; border-radius: 18px; background: rgba(242,207,157,.14); border: 1px solid var(--alt-line); color: var(--alt-ink); font-size: .9rem; line-height: 1.5; }
.form-note { margin-top: .9rem; font-size: .8rem; color: var(--alt-muted); }

/* FOOTER
   Era el único bloque de la web con degradado de fondo (--grad-deep): un
   barrido diagonal de casi negro a caramelo que no se parecía a nada más.
   Las secciones oscuras son color plano desde que existe --alt-flat, así que
   el footer también lo es: el mismo marrón de marca, un punto más oscuro que
   .alt para que se lea como el suelo de la página y no como otra sección. */
footer { background: var(--alt-bg); color: var(--alt-muted); padding: 3.2rem 0 2.6rem; text-align: center; font-size: .88rem; position: relative; overflow: hidden; }
/* La cinta caramelo se queda: es el mismo remate que cierra el hero
   (.hero::after), y es lo que cose el footer con el resto de la página. */
footer::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 5px; background: var(--grad-band); z-index: 2; }
/* Una mancha de acuarela, como en todas las secciones. Aquí no la siembra
   app.js (solo trabaja sobre .hero y section), así que va escrita a mano:
   una sola, ancha y baja, centrada bajo el logo. Tono claro y opacidad de
   fondo oscuro, los mismos que usan las secciones .alt. */
footer::after {
  content: ''; position: absolute; z-index: 0;
  left: 50%; top: 6%; width: min(560px, 92%); height: 76%;
  transform: translateX(-50%);
  background: var(--mancha-d) no-repeat center / 100% 100%;
  opacity: var(--mancha-op-alt);
  pointer-events: none;
}
footer > .wrap { position: relative; z-index: 1; }
footer .logo { display: inline-block; margin-bottom: 1rem; }
/* Sin filtro de silueta: el logo es a color y se apoya tal cual sobre el marrón. */
footer .logo-full { height: 96px; margin: 0 auto; }
.footer-legal { display: flex; justify-content: center; flex-wrap: wrap; gap: 1.2rem; margin: 1.2rem 0 .2rem; }
/* Antes eran de un gris azulado suelto (rgba(233,236,244,…)), heredado de la
   paleta anterior: el único texto de la web que no salía de un tono de marca. */
.footer-legal a { color: var(--alt-muted); font-size: .82rem; }
.footer-legal a:hover { color: var(--alt-accent); }

/* ===== AVISO DE COOKIES ===== */
.cookie-banner { position: fixed; left: 1rem; right: 1rem; bottom: 1rem; z-index: var(--z-cookie-banner); max-width: 720px; margin: 0 auto; background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 22px; box-shadow: var(--shadow); padding: 1.1rem 1.3rem; display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.cookie-banner p { font-size: .85rem; line-height: 1.5; margin: 0; flex: 1; min-width: 220px; color: var(--muted); }
.cookie-banner a { color: var(--accent); font-weight: 700; }
.cookie-banner .cookie-ok { flex-shrink: 0; padding: .6rem 1.4rem; font-size: .9rem; }

/* ===== ARTÍCULO / BLOG POST ===== */
.article { padding: 3.5rem 0 4.5rem; }
.article-head { max-width: 720px; margin: 0 auto 2.5rem; }
.article-head .eyebrow { display: block; margin-bottom: .9rem; }
.article-head h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); color: var(--primary); line-height: 1.08; margin-bottom: 1rem; }
.article-head .meta { color: var(--muted); font-size: .9rem; }
/* 720px con este tamano de letra rondaba las 78-80 cpl (ui-ux-pro-max
   audit): por encima del tope de 65-75 recomendado para lectura larga.
   600px medido con el texto real del articulo (Poppins, 9px de ancho
   medio por caracter) da ~65-70 cpl; "ch" no valia porque se basa en el
   glifo "0", mas ancho que la letra media de esta fuente. */
.article-body { max-width: 600px; margin: 0 auto; font-size: 1.12rem; }
.article-body p { color: var(--ink); margin-bottom: 1.35rem; }
.article-body h2 { font-size: 1.9rem; color: var(--primary); margin: 2.4rem 0 .8rem; }
.article-body blockquote { font-family: 'Playfair Display', serif; font-style: italic; font-size: 1.35rem; color: var(--primary); border-left: 3px solid var(--accent); padding-left: 1.3rem; margin: 2rem 0; line-height: 1.4; }
.article-body strong { color: var(--primary); }
.article-cta { max-width: 720px; margin: 3rem auto 0; padding: 2.2rem; border: 1px solid var(--line); border-radius: 26px; background: var(--surface); text-align: center; box-shadow: var(--shadow); }
.article-cta h3 { font-size: 1.5rem; color: var(--primary); margin-bottom: .5rem; }
.article-cta p { color: var(--muted); margin-bottom: 1.4rem; }
.article-back { display: inline-block; margin-top: 2.5rem; color: var(--accent); font-weight: 700; }
.article-back::before { content: '← '; }

/* ===== GUÍA DE LECTURA DE LOS ARTÍCULOS ===== */
/* La rellena app.js a partir de los <h2> del artículo. Ver GuiaLectura.astro. */

/* Barra de progreso: cuánto llevas leído. Va por encima de la barra de
   navegación (--z-nav) porque esta se esconde al bajar y el progreso no. */
.lectura-barra {
  position: fixed; top: 0; left: 0; right: 0; height: 4px;
  z-index: 60; background: transparent; pointer-events: none;
}
.lectura-barra-relleno {
  display: block; height: 100%; width: 0;
  background: var(--grad-band, var(--accent));
  transform-origin: left center;
}

/* El índice lateral. Vive fuera de la columna de texto, pegado al hueco que
   queda a la izquierda: `50vw - 620px` lo coloca justo al lado del artículo
   en pantallas grandes, y el max() evita que se salga en las medianas. */
/* El `display: block` y el `padding: 0` no sobran: más arriba hay una regla
   para `nav` a secas (la barra de navegación) que reparte a los hijos en una
   fila con espacio entre ellos. Sin esto, el título del índice y la lista de
   apartados se colocarían uno al lado del otro. */
.guia-lectura {
  display: block; padding: 0;
  position: fixed; top: 50%; transform: translateY(-50%);
  left: max(1rem, calc(50vw - 620px));
  width: 200px; z-index: 40;
  transition: opacity .35s ease, visibility .35s ease;
}
/* Fuera del artículo (portada del blog, CTA final, pie) no pinta nada:
   app.js le pone esta clase cuando el texto ya no está en pantalla. */
.guia-lectura.oculta { opacity: 0; visibility: hidden; }
.guia-lectura-titulo {
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); font-weight: 700; margin-bottom: .9rem;
}
.guia-lectura-lista { list-style: none; margin: 0; padding: 0; border-left: 2px solid var(--line); }
.guia-lectura-lista a {
  display: block; padding: .5rem 0 .5rem .9rem; margin-left: -2px;
  border-left: 2px solid transparent;
  font-size: .88rem; line-height: 1.35; color: var(--muted);
  transition: color .2s ease, border-color .2s ease;
}
.guia-lectura-lista a:hover { color: var(--primary); }
/* La sección en la que estás ahora mismo. */
.guia-lectura-lista a.activo {
  color: var(--primary); font-weight: 600; border-left-color: var(--accent);
}

/* Que el titular no se quede debajo de la barra de navegación al saltar
   desde el índice: es la barra + un respiro. */
.article-body h2 { scroll-margin-top: 6.5rem; }

/* Por debajo de 1180 px el índice no cabe al lado del texto sin pisarlo, así
   que se retira; la barra de progreso sí se queda. */
@media (max-width: 1179px) {
  .guia-lectura { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .guia-lectura { transition: none; }
}

/* ===== ANIMACIÓN AL HACER SCROLL ===== */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in-view { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: .08s; }
.reveal.d2 { transition-delay: .16s; }
.reveal.d3 { transition-delay: .24s; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ===== RESPONSIVE ===== */
@media (max-width: 820px) {
  .nav-links { position: absolute; top: 100%; right: 5%; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: 20px; padding: 1rem 1.4rem; gap: 1rem; box-shadow: var(--shadow); display: none; }
  .nav-links.open { display: flex; }
  .menu-btn { display: block; }
  .servicios-grid, .caso, .contacto-grid { grid-template-columns: 1fr; }
  .caso-foto { border-left: none; border-top: 1px solid var(--line); min-height: 220px; }
  .blog-grid { grid-template-columns: 1fr; }
}

/* ===== SERVICIOS v2 (jerarquía: peluquería principal, digital secundario) ===== */
.servicio-principal { background: var(--alt-tarjeta); border: 1px solid var(--alt-line); border-radius: 26px; padding: 2.6rem; }
.servicio-principal .tag { font-size: .75rem; letter-spacing: .15em; text-transform: uppercase; color: var(--alt-accent-texto); font-weight: 700; display: block; text-align: center; }
.servicio-principal h3 { font-size: 1.85rem; color: var(--alt-ink); margin: .3rem 0 1.4rem; text-align: center; }
/* Opcion B, elegida por Lucia el 2026-08-15 sobre /prueba-servicios: el bloque
   va centrado en la seccion, pero las dos columnas conservan sus lineas
   alineadas a la izquierda. Se ve centrado y se sigue buscando un servicio de
   un vistazo -- centrar cada linea (opcion A) rompia la columna de guiones.
   Las columnas van a "auto" y no a "1fr" para que midan lo que ocupa el texto:
   con 1fr se estirarian al ancho completo y el centrado no se notaria. */
.servicio-cols { display: grid; grid-template-columns: auto auto; gap: 0 3rem; justify-content: center; }
.servicio-cols ul { max-width: 34ch; }
.servicio-cols ul { list-style: none; }
.servicio-cols li { padding: .55rem 0 .55rem 1.6rem; position: relative; border-top: 1px solid var(--alt-line); color: var(--alt-muted); }
.servicio-cols li:first-child { border-top: none; }
.servicio-cols li::before { content: '—'; position: absolute; left: 0; color: var(--alt-accent); }
.servicio-secundario { margin-top: 1.6rem; display: flex; align-items: center; justify-content: space-between; gap: 2rem; background: rgba(255,255,255,.03); border: 1px dashed var(--alt-line); border-radius: 22px; padding: 1.6rem 2rem; }
.servicio-secundario .tag { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--alt-accent); font-weight: 700; }
.servicio-secundario h4 { font-family: 'Playfair Display', serif; font-weight: 500; color: var(--alt-ink); font-size: 1.2rem; margin: .35rem 0; }
.servicio-secundario p { color: var(--alt-muted); font-size: .95rem; margin: 0; max-width: 62ch; }
.servicio-secundario .btn { flex-shrink: 0; }

/* ===== RESEÑAS ===== */
.resena { background: var(--surface); border: 1px solid var(--line); border-radius: 22px; padding: 2rem; box-shadow: var(--shadow); }
.resena .quote { font-family: 'Playfair Display', serif; font-style: italic; font-size: 1.15rem; color: var(--muted); line-height: 1.5; }
.resena .soon-alt { display: inline-block; margin-top: 1rem; font-size: .8rem; color: var(--accent); font-weight: 700; }

/* --- Carrusel: una reseña cada vez ---
   El desplazamiento lo hace el propio navegador con scroll-snap, no un
   cálculo de píxeles en JavaScript: así funciona igual arrastrando con el
   dedo en el móvil que pulsando las flechas, y no se descuadra al cambiar
   el tamaño de la ventana. */
.carrusel { position: relative; max-width: 640px; margin: 0 auto; }
.carrusel-pista {
  display: flex;
  gap: 1.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;              /* Firefox */
  -ms-overflow-style: none;
  border-radius: 22px;
}
.carrusel-pista::-webkit-scrollbar { display: none; }
.carrusel-pista:focus-visible { outline: 3px solid var(--accent); outline-offset: 4px; }
.carrusel-pista > .resena {
  flex: 0 0 100%;
  scroll-snap-align: center;
  /* Todas iguales de alto aunque unas reseñas sean más largas que otras:
     si no, la sección pega saltos al pasar de una a otra. */
  min-height: 100%;
  display: flex;
  flex-direction: column;
}
.carrusel-pista > .resena .resena-head { margin-top: auto; padding-top: 1.3rem; }

.carrusel-flecha {
  position: absolute; top: calc(50% - 1.4rem); transform: translateY(-50%);
  z-index: 3;
  width: 46px; height: 46px; border-radius: 999px;
  display: grid; place-items: center;
  background: var(--surface); color: var(--accent);
  border: 1px solid var(--line); box-shadow: var(--shadow);
  cursor: pointer;
  transition: background .2s, color .2s, transform .2s;
}
.carrusel-flecha svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.carrusel-flecha:hover { background: var(--accent); color: var(--btn-text); }
.carrusel-flecha.ant { left: -68px; }
.carrusel-flecha.sig { right: -68px; }

.carrusel-puntos { display: flex; justify-content: center; gap: .5rem; margin-top: 1.6rem; }
.carrusel-punto {
  width: 9px; height: 9px; border-radius: 999px; padding: 0;
  border: none; background: var(--line); cursor: pointer;
  transition: background .25s, width .25s;
}
.carrusel-punto[aria-current="true"] { background: var(--accent); width: 26px; }

/* Sin sitio a los lados: las flechas bajan debajo, junto a los puntos. */
@media (max-width: 900px) {
  .carrusel { max-width: 100%; }
  .carrusel-flecha { position: static; transform: none; }
  .carrusel-puntos { align-items: center; margin-top: 1.4rem; }
  .carrusel-flecha.ant { order: 1; }
  .carrusel-puntos { order: 2; margin: 1.4rem .8rem 0; }
  .carrusel-flecha.sig { order: 3; }
  .carrusel { display: flex; flex-wrap: wrap; justify-content: center; }
  .carrusel-pista { flex: 0 0 100%; order: 0; }
}

@media (max-width: 820px) {
  /* En movil las dos columnas se apilan en una. La lista sigue centrada como
     bloque (margin auto), pero cada linea conserva su alineacion: es la misma
     idea de la opcion B, solo que en vertical. */
  .servicio-cols { grid-template-columns: minmax(0, 34ch); justify-content: center; }
  .servicio-cols ul { max-width: none; }
  .servicio-secundario { flex-direction: column; align-items: flex-start; }
}

/* ===== IMÁGENES REALES ===== */
.foto img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; border-radius: inherit; display: block; }
.caso-foto.has-img { padding: 0; overflow: hidden; }
.caso-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.caso-foto.contain { background: var(--bg-2); padding: 1rem; }
.caso-foto.contain img { object-fit: contain; border-radius: 6px; }
.article-img { display: block; width: 100%; max-width: 620px; margin: 0 auto 2.2rem; border-radius: 70px 22px 70px 22px; max-height: 360px; object-fit: cover; box-shadow: var(--shadow); }
.article-img.completa { max-width: 480px; max-height: none; height: auto; object-fit: contain; }
.article-img.alejada { object-fit: contain; object-position: center; background: var(--bg-2); }

/* ===== MEJORAS MARKETING (elegante + llamativo) ===== */
/* Línea dorada bajo los títulos de sección */
/* La línea dorada debajo de los titulares se desactiva: Anton ya ocupa muchísimo espacio visual */

/* Micro-confianza del hero */
.hero-trust { margin-top: 1.3rem; font-size: .86rem; letter-spacing: .03em; color: var(--muted); }

/* Barra de confianza — números más grandes */
.trust-item strong { font-size: 1.9rem; }

/* Burbujas flotantes de contacto (WhatsApp, Instagram, correo) */
.social-float { position: fixed; right: 22px; bottom: 22px; z-index: var(--z-social-float); display: flex; flex-direction: column; gap: 12px; }
.float-btn { width: 54px; height: 54px; border-radius: 999px; background: var(--accent); color: var(--btn-text); display: grid; place-items: center; box-shadow: 0 10px 26px -8px rgba(20,33,60,.5); transition: transform .2s, background .2s; }
.float-btn:hover { transform: scale(1.08); background: var(--accent-2); }
/* En móvil las burbujas no salen mientras se ve la portada: ahí ya está el
   botón «Reservar una cita», y en una pantalla estrecha tapaban la línea de
   «Más de 10 años de oficio · Madrid…» (auditoría del 2026-10-12). Aparecen
   en cuanto los botones de la portada salen de la pantalla. La clase la pone
   app.js; sin JavaScript no existe y las burbujas se ven siempre, como antes. */
.social-float { transition: opacity .3s ease, transform .3s ease; }
@media (max-width: 820px) {
  .social-float { right: 14px; bottom: 16px; gap: 10px; }
  .float-btn { width: 48px; height: 48px; }
  .float-btn svg { width: 25px; height: 25px; }
  .en-portada .social-float { opacity: 0; transform: translateY(14px); pointer-events: none; }
}
@media (prefers-reduced-motion: reduce) { .social-float { transition: none; } }
.float-btn svg { width: 28px; height: 28px; }
.float-btn.wa svg, .float-btn.mail svg { fill: var(--btn-text); }
.float-btn.ig svg { stroke: currentColor; fill: none; stroke-width: 2; }

/* Sección "Cómo es tu primera cita" */
.pasos-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
.paso { padding: 2rem 1.8rem; border: 1px solid var(--line); border-radius: 22px; background: var(--surface); }
.paso-num { font-family: 'Playfair Display', serif; font-size: 2.8rem; font-weight: 600; color: var(--accent); line-height: 1; display: block; margin-bottom: .3rem; }
.paso h3 { font-size: 1.3rem; color: var(--primary); margin-bottom: .4rem; }
.paso p { color: var(--muted); font-size: .95rem; }
@media (max-width: 820px) { .pasos-grid { grid-template-columns: 1fr; } }

/* ===== HERO CON FOTO DE FONDO ===== */
.hero.hero-photo { position: relative; background: linear-gradient(180deg, rgba(43,29,17,.55), rgba(43,29,17,.68)), url('img/inicio-fondo.jpeg') center/cover no-repeat; }
.hero.hero-photo .eyebrow { color: var(--accent-2); }
.hero.hero-photo .bold-text { color: #ffffff; }
.hero.hero-photo .script-text { color: var(--accent-2); -webkit-text-stroke-color: rgba(43,29,17,0.7); }
.hero.hero-photo p { color: rgba(255,255,255,.92); }
.hero.hero-photo .btn-ghost { border-color: rgba(255,255,255,.85); color: #fff; }
.hero.hero-photo .btn-ghost:hover { background: #fff; color: var(--primary); }
.hero.hero-photo .firma .growth { stroke: #f4efe4; }
.hero.hero-photo .firma .teeth line { stroke: var(--accent-2); }
.hero.hero-photo .firma .dot { fill: var(--accent-2); }

/* ===== HERO A DOS COLUMNAS (texto + foto) ===== */
.hero .hero-split { display: grid; grid-template-columns: 1.25fr 0.75fr; gap: 3rem; align-items: center; }
.hero .hero-text .firma { margin-top: 2.4rem; }
.hero-photo-side img { width: 100%; max-width: 340px; margin: 0 auto; border-radius: 26px; box-shadow: var(--shadow); display: block; }
.hero-photo-side img.hero-photo-circular { border-radius: 0; box-shadow: none; max-width: 380px; filter: drop-shadow(0 16px 38px rgba(86,58,35,.34)); }

/* Inicio: texto a la izquierda, foto grande a la derecha, todo en una pantalla */
.hero .hero-split.hero-inicio {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);  /* la foto es apaisada: manda el ancho */
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.8rem);
  text-align: left;
}
.hero-inicio .hero-text { order: 1; align-self: center; }
.hero-inicio .hero-photo-side { order: 2; align-self: stretch; position: relative; }
/* La foto se ancla al borde inferior del hero. Sin marco ni sombra: es un recorte limpio
   sobre el degradado. La mascara la desvanece por abajo para que el corte no se note. */
.hero-inicio .hero-foto-cuelga {
  position: absolute; z-index: 2;
  left: 50%; transform: translateX(-50%);
  bottom: calc(-1 * (var(--pad-b) + var(--cuelga)));
  height: calc(100% + var(--pad-b) + var(--cuelga));
  width: auto; max-width: 100%;
  object-fit: contain; object-position: bottom center;
  display: block;
  -webkit-mask-image: var(--mascara-abajo);
          mask-image: var(--mascara-abajo);
}
/* ---------- El bloque de marca del hero (variante D) ----------
   El logo corona el texto. Lleva "criterio sin prisas" dentro, así que el
   eslogan NO se repite debajo del titular: se dice una vez y en su sitio.
   Sus colores los manda el tema porque el dibujo va incrustado en la página
   (ver el comentario de index.astro): en claro --primary es marrón, en oscuro
   es crema, y el perfilado usa el color del papel. Cero reglas por tema. */
.hero-inicio .hero-marca {
  color: var(--primary);
  --logo-perfil: var(--bg);
  width: min(260px, 68%);
  margin-bottom: clamp(.7rem, 2vh, 1.3rem);
}
.hero-inicio .hero-marca svg { display: block; width: 100%; height: auto; }

/* El titular. "El cuidado" es un DIBUJO de la tipografía del logo (no la
   fuente puesta en la web: publicarla sería repartir el archivo). El texto de
   verdad va escrito al lado, oculto a la vista, para que Google lo lea. */
.hero-inicio .hero-titular { margin: 0; line-height: 1; }
.hero-inicio .hero-titular-script { display: block; color: var(--accent); }
.hero-inicio .hero-titular-script svg {
  display: block; width: auto;
  height: clamp(2.5rem, 5.6vw, 4.6rem);
  /* Playlist arranca con un trazo de entrada que deja aire a la izquierda:
     se recupera para que el titular quede a plomo con el párrafo de abajo. */
  margin-left: -.04em;
}
.hero-inicio .hero-titular-fuerte {
  display: block;
  font-family: 'Anton', sans-serif;
  font-size: clamp(2rem, 4.5vw, 4.8rem);
  line-height: .96;
  color: var(--primary);
  text-transform: uppercase;
  letter-spacing: -.005em;
  margin-top: .04em;
}

/* El subrayado de pincel: sale de pl-ornament, la tercera fuente del logo.
   preserveAspectRatio lo estira al ancho del titular, como un rotulador. */
.hero-inicio .hero-pincel { display: block; color: var(--caramelo); max-width: min(100%, 30ch); margin-top: .35rem; }
.hero-inicio .hero-pincel svg { display: block; width: 100%; height: clamp(14px, 1.9vw, 26px); }

.hero-inicio .hero-parrafo { font-size: clamp(1rem, .35vw + .92rem, 1.1rem); max-width: 46ch; margin: 1.1rem 0 1.4rem; }
.hero-inicio .btns { justify-content: flex-start; }
/* La linea de confianza NO hereda el tamano ni el ancho del parrafo: va pequena y en una sola linea */
/* text-wrap: balance = si no cabe en una linea, parte en dos equilibradas (nunca deja una palabra suelta) */
.hero-inicio .hero-text .hero-trust { font-size: .86rem; max-width: none; margin: .9rem 0 0; text-wrap: balance; }

/* ---------- La escritura del titular ----------
   Una máscara que barre de izquierda a derecha: el dibujo aparece por donde
   iría pasando la punta del rotulador. El borde del degradado es fino a
   propósito (3% del ancho de la máscara); más ancho se lee como un
   desvanecido y deja de parecer escritura.

   La clase .hero-anima la pone el JS del final de index.astro. Va así, y no
   directamente en el CSS, para que si el JS fallara la página se vea entera y
   quieta en vez de quedarse con el titular invisible para siempre. */
.hero-anima .hero-titular-script,
.hero-anima .hero-pincel {
  -webkit-mask-image: linear-gradient(100deg, #000 48.5%, rgba(0,0,0,0) 51.5%);
          mask-image: linear-gradient(100deg, #000 48.5%, rgba(0,0,0,0) 51.5%);
  -webkit-mask-size: 260% 100%;   mask-size: 260% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 100% 0;  mask-position: 100% 0;
}
.hero-anima .hero-titular-fuerte { overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.hero-anima .hero-titular-fuerte > span { display: block; }

/* El "both" del final es lo que hace que no haga falta esconder nada por
   separado: antes de que llegue su turno, cada pieza ya se queda en el primer
   fotograma de su animación (fuera de sitio o invisible). */
.hero-anima .hero-titular-script { animation: hero-escribe 2.4s .35s cubic-bezier(.42,.03,.32,.98) both; }
.hero-anima .hero-titular-fuerte > span { animation: hero-sube 1.1s 1.55s cubic-bezier(.19,1,.22,1) both; }
.hero-anima .hero-pincel { animation: hero-escribe 1s 2.5s cubic-bezier(.42,.03,.32,.98) both; }
.hero-anima .hero-aparece { animation: hero-asoma .8s var(--ret, 0s) cubic-bezier(.19,1,.22,1) both; }

@keyframes hero-escribe {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  to   { -webkit-mask-position: 0% 0;   mask-position: 0% 0; }
}
@keyframes hero-sube { from { transform: translateY(110%); } to { transform: translateY(0); } }
@keyframes hero-asoma { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* Quien pide menos movimiento lo ve quieto y completo desde el principio. */
@media (prefers-reduced-motion: reduce) {
  .hero-anima .hero-titular-script,
  .hero-anima .hero-pincel { -webkit-mask-image: none; mask-image: none; animation: none; }
  .hero-anima .hero-titular-fuerte > span { transform: none; animation: none; }
  .hero-anima .hero-aparece { opacity: 1; transform: none; animation: none; }
}

/* Pantallas bajas (portatiles de 768px de alto o menos): se aprieta todo un punto mas */
@media (min-width: 821px) and (max-height: 760px) {
  .hero:has(.hero-inicio) { --pad-b: clamp(.8rem, 2.6vh, 1.8rem); padding: clamp(.6rem, 2.2vh, 1.5rem) 0 var(--pad-b); }
  .hero-inicio .hero-titular-fuerte { font-size: clamp(1.8rem, 4vw + .5rem, 3.8rem); }
  .hero-inicio .hero-titular-script svg { height: clamp(2.2rem, 4.8vw, 3.8rem); }
  .hero-inicio .hero-marca { width: min(215px, 60%); margin-bottom: .5rem; }
  .hero-inicio .hero-parrafo { font-size: 1rem; margin: .8rem 0 1.1rem; }
  .hero-inicio .hero-trust { margin-top: .7rem; }
}
.hero-logo { display: flex; align-items: center; gap: .7rem; margin-top: 2.4rem; }
.hero-logo-mark { width: 42px; height: 42px; flex-shrink: 0; }
.hero-logo-mark ellipse { fill: var(--accent); }
.hero-logo-text { font-family: 'Playfair Display', serif; font-weight: 600; font-size: 1.75rem; color: var(--primary); line-height: 1; }
.hero-logo-text span { color: var(--accent); }
@media (max-width: 820px) {
  .hero .hero-split { grid-template-columns: 1fr; gap: 2.2rem; }
  .hero .hero-text .firma { display: none; }
  /* En movil se apila: foto arriba, texto centrado debajo, sin forzar pantalla completa
     ni efecto de cuelgue (en vertical no hay sitio y se comeria el titular) */
  /* La foto es mucho mas pequena al apilarse: el desvanecido se reduce en proporcion */
  .hero:has(.hero-inicio) { --pad-b: 2.4rem; --fade: 62px; min-height: 0; display: block; padding: 2rem 0 var(--pad-b); }
  .hero .hero-split.hero-inicio { grid-template-columns: 1fr; gap: 1.6rem; text-align: center; }
  .hero-inicio .hero-photo-side { order: 1; align-self: auto; }
  .hero-inicio .hero-text { order: 2; }
  /* Todo el bloque de marca se centra al apilarse: logo, titular, pincel y
     párrafo. Los dibujos son <svg> dentro de <span>, así que se centran con
     margin auto, no con text-align. */
  .hero-inicio .hero-marca,
  .hero-inicio .hero-titular-script svg,
  .hero-inicio .hero-pincel { margin-left: auto; margin-right: auto; }
  .hero-inicio .hero-titular, .hero-inicio .hero-parrafo { text-align: center; margin-left: auto; margin-right: auto; }
  .hero-inicio .hero-pincel { max-width: min(320px, 80%); }
  .hero-inicio .btns { justify-content: center; }
  .hero-inicio .hero-foto-cuelga {
    position: static; transform: none; height: auto; width: min(84%, 330px);
    margin: 0 auto; bottom: auto;
  }
}
@media (max-width: 520px) {
  .hero:has(.hero-inicio) { --pad-b: 1rem; padding: 1.1rem 0 var(--pad-b); }
  .hero .hero-split.hero-inicio { gap: .6rem; }
  .hero:has(.hero-inicio) { --fade: 44px; }
  .hero-inicio .hero-foto-cuelga { width: min(62%, 232px); }
  .hero-inicio .hero-marca { width: min(210px, 62%); margin-bottom: .5rem; }
  .hero-inicio .hero-parrafo { margin: .8rem auto .95rem; }
  .hero-inicio .hero-text .hero-trust { margin-top: .6rem; }
}

/* ===== BARRA DE CONFIANZA ===== */
.trust-bar { background: var(--surface); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.trust-bar .wrap { display: flex; justify-content: center; gap: 3rem; flex-wrap: wrap; padding: 1.8rem 0; text-align: center; }

.trust-item { display: flex; flex-direction: column; gap: .2rem; }
.trust-item strong { font-family: 'Playfair Display', serif; color: var(--primary); font-size: 1.4rem; line-height: 1; }
.trust-item span { font-size: .82rem; color: var(--muted); letter-spacing: .04em; text-transform: uppercase; }

/* ===== EN CADA PERRO: carrusel de fichas (tipos de trabajo) ===== */
/* Nació como página de prueba (/prueba-trabajos, 2026-08-06) para comparar
   con la antigua rejilla de tres fotos recortadas; Lucía decidió sustituirla
   el 2026-08-09 y esto pasó a vivir aquí, con el resto de la web. */
.tw { position: relative; max-width: 860px; margin: 0 auto; }
.tw-pista {
  display: flex; gap: 1.5rem; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; padding: .4rem;
}
.tw-pista::-webkit-scrollbar { display: none; }
.tw-pista:focus-visible { outline: 3px solid var(--accent); outline-offset: 4px; }

.tw-ficha {
  /* Escala de espaciado propia de la ficha (Lucía, 2026-08-10, auditoría
     ui-ux-pro-max: "espaciados de acuerdo a un sistema coherente"). Antes
     había valores sueltos (.4rem, .7rem, .8rem...) sin relación entre sí;
     ahora todo el ritmo vertical de dentro de la ficha sale de esta escala
     de 4px, así que un respiro y el doble de ese respiro son siempre el
     mismo número, se vea donde se vea. Los saltos grandes (sp-5, sp-6) son
     a propósito más separados entre sí que los pequeños: así el espacio en
     sí marca qué va junto y qué es un bloque nuevo — jerarquía por
     espaciado, no solo por tamaño de letra. Lucía, 2026-08-10: "que las
     cards crezcan un poco verticalmente" — aquí ya no hay que pelear cada
     píxel contra el alto de pantalla, solo que la relación entre huecos
     tenga sentido. */
  --sp-1: .25rem;  /* 4px */
  --sp-2: .5rem;   /* 8px */
  --sp-3: .75rem;  /* 12px */
  --sp-4: 1rem;    /* 16px */
  --sp-5: 1.5rem;  /* 24px */
  --sp-6: 2rem;    /* 32px */

  flex: 0 0 100%; scroll-snap-align: center;
  display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1fr);
  gap: clamp(.85rem, 2vw, 1.5rem); align-items: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 26px; padding: clamp(.85rem, 1.6vw, 1.25rem);
  box-shadow: var(--shadow);
}

/* La foto: forma orgánica de marca, pero suave. El truco contra el recorte
   es la proporción 4/3.6 + object-position arriba: en una foto de perro
   sentado, lo que importa está en la mitad de arriba. La altura máxima
   (Lucía, 2026-08-09: "quiero que quepa entera en pantalla") es la segunda
   red de seguridad: aunque la columna sea ancha, la foto no crece más allá
   de eso y se recorta con object-fit en vez de alargar la tarjeta. */
/* El recorte (border-radius + overflow) vive en la FIGURA, no en la foto:
   así, cuando el editor aplica un zoom con transform: scale() a la foto
   (2026-08-09, "poder acercar o alejar la fotografía"), lo que se escapa del
   contorno queda cortado por la figura en vez de agrandar la burbuja entera.
   `height: auto` en la figura es obligatorio: el <img> lleva los atributos
   width y height para que el navegador reserve el hueco y no salte la
   página al cargar, pero esos atributos fijarían la altura si el
   aspect-ratio estuviera en el propio <img>. */
.tw-retrato {
  position: relative; margin: 0; overflow: hidden;
  aspect-ratio: 4 / 3.8; max-height: min(39vh, 308px);
  border-radius: 46% 54% 40% 60% / 34% 32% 68% 66%;
  transition: border-radius .6s ease;
  /* Algunas fotos llegan sin fondo (recorte con IA). Si el PNG tiene zonas
     transparentes, aquí se ven del mismo crema (o marrón, ver más abajo) que
     el resto de la web, en vez de blanco o a cuadros — las fotos con fondo
     normal no cambian nada, porque no tienen ningún hueco transparente que
     enseñar. */
  background: var(--bg-2);
}
.tw-ficha:hover .tw-retrato { border-radius: 34% 66% 52% 48% / 44% 40% 60% 56%; }
.tw-retrato img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Fondo alterno crema/marrón (Lucía, 2026-08-09): un perro claro destaca
   más sobre fondo oscuro, y uno oscuro sobre fondo claro. En vez de decidir
   foto a foto, alterna por posición en el carrusel (fichas impares =
   marrón), que ya casa bien con la mayoría de las fotos actuales porque los
   perros claros y oscuros se reparten con bastante regularidad. Si una foto
   nueva queda mal así, se puede pedir el cambio puntual. */
/* RETIRADO el 2026-10-12 (Lucía: "todos los fondos de las fotos tienen que
   ser de color crema, tanto en las tarjetas como en el collage"). Una foto
   sin data-fondo cae ahora en crema, igual que las demás, y con el tono fijo
   de más abajo para que el modo oscuro no la apague. */
.tw-retrato, .tw-ejemplo-btn img, .mas-btn img, .visor img { background: #f2e7d5; }
/* Fondo elegido foto a foto (Lucía, 2026-10-12): cuando la alternancia no
   acierta, la foto dice su color con data-fondo y gana a la regla de arriba.
   Solo se nota en las fotos recortadas, que son las que dejan ver el fondo. */
/* Colores fijos, no var(--bg-2) / var(--primary): esas dos se dan la vuelta
   en modo oscuro, y un perro blanco pedido "sobre marrón" acabaría sobre
   crema. El fondo de una foto es parte de la foto: no cambia con el tema. */
.tw-ficha .tw-retrato[data-fondo="crema"],
.tw-ficha .tw-ejemplo-btn[data-fondo="crema"] img,
.mas-btn[data-fondo="crema"] img,
.visor img[data-fondo="crema"] { background: #f2e7d5; }
.tw-ficha .tw-retrato[data-fondo="marron"],
.tw-ficha .tw-ejemplo-btn[data-fondo="marron"] img,
.mas-btn[data-fondo="marron"] img,
.visor img[data-fondo="marron"] { background: #563a23; }

/* Hueco marcado para el trabajo que todavía no tiene foto. Hereda tamaño,
   forma y fondo de .tw-retrato (misma figura, dos clases); aquí solo lo
   propio de estar vacía. */
.tw-falta {
  display: grid; place-content: center; gap: .8rem;
  border: 2px dashed var(--accent-2); text-align: center; padding: 2rem;
}
.tw-falta img { width: 118px; height: auto; border-radius: 0; opacity: .75; margin: 0 auto; }
/* var(--primary), no var(--accent-2): el tostado sobre el fondo crema de
   este hueco da ~3.65:1, por debajo del 4.5:1 que pide un texto de este
   tamaño en negrita. El marrón oscuro de --primary sube a ~8.5:1. */
.tw-falta figcaption { color: var(--primary); font-size: .82rem; font-weight: 700; letter-spacing: .04em; }

.tw-ejemplos { position: relative; margin-top: var(--sp-3); display: flex; align-items: center; gap: var(--sp-2); }
.tw-ejemplos-tit {
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); writing-mode: vertical-rl; transform: rotate(180deg);
}
/* Fila de miniaturas SIEMPRE en una sola línea (Lucía, 2026-08-09: "no
   pueden ir en dos líneas"): en vez de envolver a una segunda fila, la que
   no cabe se desliza con scroll horizontal — mismo lenguaje que el carrusel
   grande y el de reseñas, así no rompe el patrón de la web. La barra de
   scroll es fina y semitransparente a propósito (Lucía, 2026-08-10: "casi
   transparente, para quien no sepa mover el touchpad") — ver mixin de
   scrollbar más abajo. */
.tw-ejemplos-lista {
  display: flex; flex-wrap: nowrap; gap: var(--sp-2);
  overflow-x: auto; padding-bottom: 6px;
}
/* Miniatura clicable: pincharla convierte esa foto en la foto grande de la
   ficha (mini-carrusel). El aro marca cuál se ve grande ahora mismo, sin
   depender solo del color. */
.tw-ejemplo-btn {
  padding: 0; border: 2px solid transparent; border-radius: 14px; cursor: pointer;
  background: none; display: block; line-height: 0; transition: border-color .2s;
  flex-shrink: 0; overflow: hidden; /* corta el zoom de la foto, ver .tw-retrato */
}
.tw-ejemplo-btn img {
  width: 62px; height: 62px; object-fit: cover;
  border-radius: 12px; border: 1px solid var(--line); display: block;
  background: var(--bg-2); /* mismo motivo que .tw-retrato img: recortes sin fondo */
}
.tw-ejemplo-btn[aria-current="true"] { border-color: var(--accent); }
.tw-ejemplo-btn:hover { border-color: var(--accent-2); }
.tw-ejemplo-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* ---------- jerarquía de espaciado del bloque de texto ---------- */
/* Cada salto de tamaño dice algo: sp-2 (8px) es "esto va con lo de al lado"
   (número+kicker), sp-4 (16px) es "nuevo párrafo dentro del mismo tema"
   (título→texto), sp-5/sp-6 (24-32px) es "salgo del texto y entro en las
   etiquetas" — el hueco más grande de la ficha, a propósito, porque es el
   cambio de tema más grande. */
.tw-cabecera { display: flex; align-items: baseline; gap: var(--sp-3); margin-bottom: var(--sp-2); }
/* --accent-2 y no --caramelo: el caramelo claro sobre la tarjeta blanca daba
   2,2 a 1, y un número de 24 px necesita al menos 3. En móvil va sobre la foto
   oscurecida y ahí sí conserva el caramelo (regla de más abajo). */
.tw-num { font-family: 'Anton', sans-serif; font-size: 1.5rem; color: var(--accent-2); line-height: 1; }
.tw-texto h3 { font-family: 'Playfair Display', serif; font-size: clamp(1.3rem, 2.4vw, 1.7rem); color: var(--primary); line-height: 1.15; margin-bottom: var(--sp-4); }
.tw-prosa { color: var(--muted); font-size: .95rem; margin-bottom: var(--sp-6); }

/* Mixin de scrollbar fino y discreto: se repite igual en las tres listas
   (chips, razas, miniaturas) para que las tres se vean y se noten igual. */
.tw-chips, .tw-razas, .tw-ejemplos-lista { scrollbar-width: thin; scrollbar-color: var(--barra-desplaz) transparent; }
.tw-chips::-webkit-scrollbar, .tw-razas::-webkit-scrollbar, .tw-ejemplos-lista::-webkit-scrollbar { height: 5px; }
.tw-chips::-webkit-scrollbar-track, .tw-razas::-webkit-scrollbar-track, .tw-ejemplos-lista::-webkit-scrollbar-track { background: transparent; }
.tw-chips::-webkit-scrollbar-thumb, .tw-razas::-webkit-scrollbar-thumb, .tw-ejemplos-lista::-webkit-scrollbar-thumb { background: var(--barra-desplaz); border-radius: 999px; }

/* Sombra de desborde: NO va en la propia lista que se desplaza, porque las
   pastillas de dentro tienen fondo opaco y la taparían (bug real, visto por
   Lucía 2026-08-10: solo se veía en razas, que son de contorno, no en
   etiquetas, que son rellenas). Va en una caja envolvente aparte, como capa
   por encima: así gana siempre, tenga o no fondo lo último que se ve. */
.tw-chips-caja, .tw-razas-caja { position: relative; }
.tw-chips-caja::after, .tw-razas-caja::after, .tw-ejemplos::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 6px; width: 28px;
  pointer-events: none; opacity: 0; transition: opacity .25s ease; z-index: 1;
  background: linear-gradient(to right, transparent, var(--sombra-desborde) 100%);
}
.tw-chips-caja.tiene-desborde::after, .tw-razas-caja.tiene-desborde::after, .tw-ejemplos.tiene-desborde::after {
  opacity: 1;
}

/* Las dos filas de chips van en una sola línea con scroll horizontal si no
   caben (Lucía, 2026-08-09), igual que la fila de miniaturas: más coherente
   que partir en dos líneas y no depende de cuántas etiquetas o razas haya. */
.tw-chips {
  display: flex; flex-wrap: nowrap; gap: var(--sp-2); list-style: none; margin: 0;
  overflow-x: auto; padding-bottom: 6px;
}
.tw-chips li {
  display: inline-flex; align-items: center; gap: .4rem; flex-shrink: 0;
  background: var(--bg-2); color: var(--primary);
  border-radius: 999px; padding: .38rem .8rem; font-size: .82rem; font-weight: 600;
}
.tw-chips svg { width: 15px; height: 15px; flex-shrink: 0; fill: none; stroke: var(--accent); stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* Línea separadora entre las dos filas de pastillas, con su propio hueco a
   cada lado (Lucía, 2026-08-10: "una línea horizontal separadora... y un
   poco más de espacio entre ellas"). Mismo color que el borde de las
   tarjetas, para que no meta un elemento nuevo al lenguaje visual. */
.tw-divisor { border: none; border-top: 1px solid var(--line); margin: var(--sp-4) 0; }

/* Chips de razas: mismo lenguaje visual que .tw-chips pero en contorno, para
   que no se confundan con las etiquetas de técnica de arriba. El icono es
   Benji en pequeño (Lucía, 2026-08-09: el trazo de perro genérico "parecía
   la cabeza de un gato"). */
.tw-razas {
  display: flex; flex-wrap: nowrap; gap: var(--sp-2); list-style: none; margin: 0;
  overflow-x: auto; padding-bottom: 6px;
}
.tw-razas li {
  display: inline-flex; align-items: center; gap: .35rem; flex-shrink: 0;
  background: none; color: var(--muted); border: 1px solid var(--line);
  border-radius: 999px; padding: .32rem .75rem; font-size: .78rem; font-weight: 600;
}
.tw-raza-icon { width: 15px; height: 15px; flex-shrink: 0; object-fit: contain; }

/* Flechas: mismo aspecto que las del carrusel de reseñas, para que la web
   siga pareciendo una sola web. */
.tw-flecha {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 46px; height: 46px; border-radius: 999px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); color: var(--primary);
  display: grid; place-items: center; transition: background .2s, color .2s;
}
.tw-flecha svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.tw-flecha:hover { background: var(--accent); color: var(--btn-text); }
.tw-flecha.ant { left: -66px; }
.tw-flecha.sig { right: -66px; }

/* El botón "Leer" y la barrita del cajón son piezas EXCLUSIVAS del móvil: en
   el ordenador la tarjeta enseña todo el texto y no hay nada que abrir. Se
   ocultan aquí y se encienden abajo, dentro de la regla de pantalla estrecha.
   Van con display:none (no con visibility ni opacidad) para que tampoco los
   anuncie un lector de pantalla ni los pille el tabulador. */
.tw-leer, .tw-asa { display: none; }

.tw-puntos { display: flex; justify-content: center; gap: .1rem; margin-top: .5rem; }
/* El punto que se ve mide 10px, pero el botón real mide 44x44: el dedo
   necesita más zona de la que se pinta (misma regla táctil que
   .carrusel-punto de las reseñas, más abajo). */
.tw-punto {
  width: 44px; height: 44px; border-radius: 999px; border: none; padding: 0;
  background: none; cursor: pointer; display: grid; place-items: center;
}
.tw-punto::before {
  content: ''; display: block; width: 10px; height: 10px; border-radius: 999px;
  background: var(--line); transition: width .25s, background .25s;
}
.tw-punto[aria-current="true"]::before { background: var(--accent); width: 26px; }

/* Texto solo para lectores de pantalla: anuncia el cambio de ficha sin
   ocupar sitio en la pantalla. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

@media (max-width: 1120px) {
  /* Por debajo de 1120 px la flecha ya no cabe fuera de la tarjeta, y
     dejarla encima taparía la foto. Bajan a una franja propia bajo el
     carrusel, al lado de los puntos. */
  .tw { padding-bottom: 64px; }
  .tw-flecha { top: auto; bottom: 0; transform: none; }
  .tw-flecha.ant { left: calc(50% - 62px); }
  .tw-flecha.sig { right: calc(50% - 62px); }
  .tw-puntos { margin-top: 1.2rem; }
}
@media (max-width: 900px) {
  .tw-ficha { grid-template-columns: 1fr; }
  /* En vertical la foto ya no compite con el texto: se puede dar más aire. */
  .tw-retrato img, .tw-falta { aspect-ratio: 5 / 4; }
  .tw-ejemplos { justify-content: flex-start; }
  .tw-ejemplos-tit { writing-mode: horizontal-tb; transform: none; }

  /* ----- (1) Que la tarjeta quepa (Lucía, 2026-08-31) -----
     Medido en un móvil de 375 px: la tarjeta salía 457 y se comía 119 px
     por la derecha, así que era IMPOSIBLE verla entera.

     La culpa no es de ninguna medida escrita en esta hoja: es el valor por
     defecto `min-width: auto`. Todo elemento de flex o de rejilla se niega a
     encogerse por debajo de lo que mide su contenido más ancho, y dentro de
     la ficha hay tres filas que por decisión de Lucía NO se parten en dos
     líneas (etiquetas, razas y miniaturas). Al no caber, el navegador prefiere
     ensanchar la tarjeta antes que estrechar la fila. Con `min-width: 0` se
     invierte esa preferencia: manda el ancho de la tarjeta y las filas se
     desplazan por dentro, que es justo lo que ya hacían y para lo que llevan
     su `overflow-x: auto`.

     Hace falta en TODA la cadena —de la ficha hasta cada fila—, porque basta
     un eslabón sin poner para que el empujón siga subiendo hasta arriba. */
  .tw-ficha,
  .tw-media, .tw-texto,
  .tw-ejemplos, .tw-ejemplos-lista,
  .tw-chips-caja, .tw-razas-caja,
  .tw-chips, .tw-razas { min-width: 0; }

  /* ----- (2) El asomo, o «peek» (Lucía eligió la opción B, 2026-08-31) -----
     Lucía: "es muy difícil deducir que se puede deslizar hacia los lados".
     Tenía razón: una tarjeta centrada y completa parece una tarjeta suelta,
     y el punto de debajo no lo desmiente.

     El arreglo no es un cartel que diga "desliza", es geometría: la ficha se
     estrecha para que asome el canto de la siguiente. Un trozo cortado se lee
     solo como "hay más ahí detrás" — sin texto, sin idioma y sin instrucciones.

     Las cuentas, en un móvil de 375 (pista de 338):
       ficha 273 + 2 huecos de 10 + 2 asomos de 22 = 338
     El asomo se queda entre 20 y 24 px a propósito: por debajo parece un fallo
     de alineación, y por encima empieza a competir con la ficha que se lee.

     Ojo con el 100% del `calc`: se mide contra el hueco interior de la pista,
     que ya ha descontado su propio `padding` de .4rem. Por eso el número que
     se resta aquí (52) no coincide con los 64 px de asomo+hueco de la cuenta
     de arriba. Medido: ficha de 273 y asomo de 22 en un móvil de 375.

     La primera ficha es la excepción: como no se puede desplazar más a la
     izquierda, se queda pegada al margen y enseña un asomo mayor. Lejos de ser
     un fallo, es el mejor momento para la pista visual — es justo la ficha que
     se ve al llegar a la sección. */
  .tw-pista { gap: .625rem; }
  .tw-ficha { flex-basis: calc(100% - 52px); }

  /* ----- (3) El cajón: la tarjeta enseña foto y título, el texto se pide -----
     Lucía, 2026-08-31: "todavía se ve demasiado recargado... las tarjetas sólo
     con las fotos y el título y si la persona quiere leer información de un
     tipo de trabajo en concreto, que se deslice un acordeón".

     Eligió este diseño (la «C») de cuatro que se le enseñaron en maqueta. Lo
     que lo distingue de un acordeón normal: la tarjeta NO cambia de tamaño al
     abrirse. El cajón sube por dentro, sobre la foto. Un acordeón que crece
     empuja al resto y, dentro de un carrusel, da la sensación de que la página
     salta cada vez que tocas algo.

     Esto vale SOLO para pantalla estrecha, por petición expresa suya: "las
     tarjetas que están en la versión pc me gustan como están". Arriba de 900 px
     no cambia ni un píxel — los envoltorios nuevos del HTML son cajas sueltas
     sin estilo propio, y los botones nuevos están ocultos. */

  /* La tarjeta pasa de rejilla de dos columnas a un lienzo con capas. La
     proporción 4/5 la ata al ancho, así que se adapta sola a cada teléfono en
     vez de llevar un alto escrito a mano; el tope en vh es la red de seguridad
     para tabletas, donde 4/5 de una tarjeta ancha se iría de pantalla. */
  /* La tarjeta GIRA (idea de Diego, 2026-08-31). El cajón anterior dejaba el
     texto en una ventanita de 234 px mientras 409 estaban ocupados por una foto
     que ya habías visto; girando, el dorso se queda con la tarjeta entera.

     `overflow` tiene que quedarse en `visible`: cualquier recorte —overflow,
     clip-path, filter, opacidad...— obliga al navegador a aplastar el 3D y el
     giro se vería plano. Por eso el recorte de las esquinas baja a cada cara.

     La perspectiva va dentro del propio `transform` en vez de en la pista: la
     pista se desplaza de lado, y una perspectiva puesta ahí haría que las
     tarjetas se deformaran según lo lejos que estuvieran del centro. */
  .tw-ficha {
    display: block; position: relative;
    aspect-ratio: 2 / 3; max-height: 62vh;
    padding: 0; overflow: visible;
    transform-style: preserve-3d;
    transform: perspective(1100px) rotateY(0deg);
    transition: transform .62s cubic-bezier(.4, .12, .22, 1);
  }
  .tw-ficha.tw-abierta { transform: perspective(1100px) rotateY(180deg); }

  /* Las dos caras: cada una tapa la de detrás y se recorta por su cuenta.
     `visibility` con retardo saca del alcance del lector de pantalla y del
     tabulador la cara que no toca, a mitad del giro — `backface-visibility`
     sola la esconde de la vista, pero la deja navegable. */
  .tw-media, .tw-titulo, .tw-leer, .tw-detalle {
    backface-visibility: hidden; -webkit-backface-visibility: hidden;
    transition: visibility 0s .31s;
  }
  /* 25 px y no `inherit`: las caras van a `inset: 0`, o sea por dentro del
     borde de 1 px de la tarjeta, así que su radio es el de la tarjeta (26)
     menos ese borde. Y `inherit` además daba 0 en el dorso, porque hereda de
     `.tw-texto` —su padre en el HTML, sin radio ninguno— y no de la tarjeta:
     salía con las esquinas de arriba cuadradas asomando por fuera del
     redondeo. Lo mismo vale para `.tw-titulo`, más abajo. */
  .tw-media { border-radius: 25px; overflow: hidden; }
  .tw-detalle { border-radius: 25px; transform: rotateY(180deg); visibility: hidden; }
  .tw-ficha.tw-abierta .tw-detalle { visibility: visible; }
  .tw-ficha.tw-abierta .tw-media,
  .tw-ficha.tw-abierta .tw-titulo,
  .tw-ficha.tw-abierta .tw-leer { visibility: hidden; }

  /* La foto pasa a ser el fondo de la tarjeta. Aquí se pierde la forma
     orgánica del retrato a propósito: recortar una silueta irregular DENTRO de
     un rectángulo que ya está recortado deja esquinas muertas de fondo crema.
     El redondeo lo pone ahora la tarjeta. */
  .tw-media, .tw-retrato, .tw-falta { position: absolute; inset: 0; }
  .tw-retrato, .tw-falta {
    height: 100%; width: 100%; max-height: none;
    aspect-ratio: auto; border-radius: 0;
  }
  /* Anula el `aspect-ratio: 5/4` que esta misma regla de móvil le pone a la
     foto unas líneas más arriba: ahí servía para dar aire cuando la ficha era
     una columna; aquí la foto tiene que llenar la tarjeta entera. */
  .tw-retrato img { height: 100%; aspect-ratio: auto; }
  .tw-ficha:hover .tw-retrato { border-radius: 0; }
  .tw-leer { display: block; }

  /* El título se sube sobre la foto, con un degradado que le garantiza el
     contraste haga la foto lo que haga.

     Ya no reserva hueco a la derecha: el botón "Leer" se fue arriba justamente
     para eso (Lucía, 2026-08-31: "los títulos, cuando son un poco más largos,
     se tienen que espaciar y no queda bien alineado"). Con los 244 px libres y
     el tamaño de abajo, los siete títulos entran en una línea. */
  .tw-titulo {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    border-radius: 0 0 25px 25px;
    padding: 3.4rem .9rem .9rem;
    /* El degradado tiene que sostener el texto sobre CUALQUIER foto, y varias
       de las suyas son de fondo claro y perro claro. La primera versión se
       desvanecía al 46 % y el número y la etiqueta caían ya sobre la zona
       clara: se leían mal. Ahora aguanta opaco casi hasta arriba del rótulo y
       solo se disuelve en el último tramo. */
    background: linear-gradient(to top,
      rgba(20,13,8,.96) 0%,
      rgba(20,13,8,.90) 42%,
      rgba(20,13,8,.62) 72%,
      rgba(20,13,8,0) 100%);
    pointer-events: none;
  }
  .tw-titulo .tw-cabecera { margin-bottom: .1rem; }
  .tw-titulo .tw-num { color: var(--caramelo); }
  .tw-titulo .eyebrow { color: #e8c79a; }
  /* 1 rem, medido y no elegido a ojo: el título más largo de los siete es
     "PDAE (Perro de Aguas Español)". A 1,12 rem pedía 256 px y solo hay 244,
     por eso partía en dos líneas y quedaba descolgado. A 1 rem el más largo se
     queda en 229 y sobran 15 px de margen. Si algún día entra un título más
     largo no se rompe nada: parte en dos líneas y el rótulo crece hacia
     arriba, como hacía antes. */
  .tw-titulo h3 {
    color: #fdf6ec; margin-bottom: 0;
    font-size: 1rem; line-height: 1.25;
  }

  /* Arriba a la derecha, donde no le quita ancho al título. */
  .tw-leer {
    position: absolute; top: .8rem; right: .8rem; z-index: 4;
    background: var(--accent); color: var(--btn-text); border: none;
    border-radius: 999px; padding: .5rem 1.05rem; cursor: pointer;
    font-family: inherit; font-size: .74rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    box-shadow: 0 6px 16px -6px rgba(0,0,0,.55);
    transition: background .2s, visibility 0s .31s;
  }
  .tw-leer:focus-visible { outline: 3px solid var(--accent-2); outline-offset: 2px; }

  /* ---------- el dorso ---------- */
  /* Ocupa la tarjeta entera: ese era el sentido de girarla. El cajón anterior
     dejaba 234 px útiles de los 409 de la tarjeta; aquí son los 409 menos la
     cabecera del botón "Volver". */
  .tw-texto { display: contents; }
  .tw-detalle {
    position: absolute; inset: 0; z-index: 3;
    background: var(--surface); overflow: hidden;
    display: flex; flex-direction: column;
  }

  /* "Volver": mismo sitio y mismo tamaño que "Leer" en la cara de delante, para
     que el dedo no tenga que buscarlo después del giro. En contorno y no
     relleno, porque aquí no hay foto que le reste contraste y un segundo botón
     macizo competiría con las etiquetas. */
  .tw-asa {
    display: inline-flex; align-items: center; gap: .35rem; flex-shrink: 0;
    align-self: flex-end; margin: .8rem .8rem .2rem;
    padding: .42rem .9rem .42rem .7rem;
    background: var(--bg-2); color: var(--primary);
    border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
    font-family: inherit; font-size: .74rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
  }
  .tw-asa svg {
    width: 14px; height: 14px; fill: none; stroke: currentColor;
    stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  }
  .tw-asa:hover { background: var(--accent); color: var(--btn-text); border-color: var(--accent); }
  .tw-asa:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

  /* Si aun así el texto no cabe, se desplaza aquí dentro y no en la página:
     `overscroll-behavior` evita que al llegar al final arrastre la página
     entera, que dentro de un carrusel se siente como un resbalón. */
  .tw-detalle-cuerpo {
    overflow-y: auto; padding: 0 .9rem .9rem;
    display: flex; flex-direction: column;
    overscroll-behavior: contain;
  }
  .tw-detalle-cuerpo .tw-prosa { margin-bottom: var(--sp-4); }
  .tw-detalle-cuerpo .tw-divisor { margin: var(--sp-3) 0; }

  /* Las fotos, grandes y las últimas (Lucía: "quiero que cuando se dé la
     vuelta, puedas ver las fotos y el texto claramente"). Van al final porque
     quien gira la tarjeta viene a leer; y suben de 62 a 78 px porque ahora hay
     sitio de sobra y a este tamaño se distingue el corte, no solo el perro.
     app.js es quien las trae aquí desde debajo de la foto: en el ordenador
     siguen donde estaban. */
  .tw-detalle-cuerpo .tw-ejemplos {
    margin: auto 0 0; padding-top: var(--sp-3);
    /* El rótulo se pone ENCIMA en vez de al lado: a su lado se comía casi 90
       de los 244 px de ancho y solo cabían dos fotos. Encima caben tres. */
    flex-direction: column; align-items: stretch; gap: var(--sp-1);
  }
  .tw-detalle-cuerpo .tw-ejemplos-tit { color: var(--muted); }
  .tw-detalle-cuerpo .tw-ejemplo-btn img { width: 78px; height: 78px; }
}

/* Quien tiene "reducir movimiento" activado en su sistema no espera que una
   tarjeta gire en 3D delante de sus ojos: para mucha gente con mareo o vértigo
   ese es justo el movimiento que peor sienta. La tarjeta cambia igual de cara,
   pero de golpe. El intercambio de visibilidad pierde también su retardo, que
   solo existía para ocurrir a mitad del giro. */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .tw-ficha { transition: none; }
  .tw-media, .tw-titulo, .tw-leer, .tw-detalle { transition: none; }
}
@media (prefers-reduced-motion: reduce) {
  .tw-retrato img { transition: none; }
}

/* ===== MIS TRABAJOS: collage tipo tetris ===== */
/* Lucía, 2026-08-10: "que quede asimétrico... formando un tetris, piezas
   grandes y pequeñas, que no sea excesivamente grande y que en el móvil se
   vean muchas fotos juntas sin saturar". Rejilla CSS con filas finas
   (--fila) para que cada pieza encaje sin desperdiciar sitio, y una de cada
   cinco fotos ocupa 2×2 en vez de 1×1 (clase `.grande`, puesta desde el
   HTML). A diferencia del carrusel de arriba, aquí SÍ se recorta un poco
   (object-fit: cover) — es un mosaico de piezas iguales a propósito; el
   encuadre de cada foto ya se decidió foto a foto en "Ajustar encuadre".*/
.mas {
  display: grid; grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: var(--fila, 128px); grid-auto-flow: dense;
  gap: 1rem;
}
.mas-item { margin: 0; }
.mas-item.grande { grid-column: span 2; grid-row: span 2; }
/* Escalonado propio: la clase global .reveal solo trae d1/d2/d3 y aquí hay
   muchas más fotos que eso. El retardo sale del índice que pone el HTML. */
.mas-item { transition-delay: calc(var(--i) * 45ms); }

.mas-btn {
  display: block; width: 100%; height: 100%; padding: 0; border: 1px solid var(--alt-line);
  border-radius: 16px; overflow: hidden; cursor: zoom-in; background: none;
  transition: transform .4s ease, box-shadow .4s ease;
}
.mas-btn img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s ease; background: var(--bg-2); }
.mas-btn:hover { transform: translateY(-4px); box-shadow: 0 18px 34px -20px rgba(0,0,0,.55); }
.mas-btn:hover img { transform: scale(1.045); }
.mas-btn:focus-visible { outline: 3px solid var(--alt-accent); outline-offset: 3px; }

/* Menos columnas y filas más bajas en pantallas pequeñas — piezas más
   chicas para que quepan más juntas sin verse enormes (Lucía, 2026-08-10). */
@media (max-width: 900px) { .mas { grid-template-columns: repeat(3, 1fr); --fila: 100px; } }
@media (max-width: 560px) {
  .mas { grid-template-columns: repeat(2, 1fr); --fila: 84px; gap: .6rem; }
  /* Una pieza de 2×2 en una rejilla de 2 columnas ocupa el ancho entero:
     se queda solo en más alta (2 filas), no también más ancha. */
  .mas-item.grande { grid-column: span 1; grid-row: span 2; }
}
@media (prefers-reduced-motion: reduce) { .mas-btn, .mas-btn img { transition: none; } }

/* Collage corto en móvil (auditoría del 2026-10-12): con las 23 fotos a dos
   columnas ocupaba casi tres pantallas y empujaba reseñas y contacto muy
   abajo. Se enseñan 8 y un botón despliega el resto. La clase .mas-corta la
   pone app.js; sin ella (o en pantallas anchas) se ve entero. */
.mas-ver { display: none; }
@media (max-width: 560px) {
  .mas.mas-corta .mas-item:nth-child(n+9) { display: none; }
  .mas-ver:not([hidden]) { display: block; margin: 1.2rem auto 0; }
}

/* ---------- visor de la galería ---------- */
/* El diálogo ocupa toda la pantalla y centra la foto con grid, en vez de
   fiarse del centrado por defecto del navegador (margin:auto). Así la zona
   "fuera de la foto" es el propio <dialog>, y cerrar al pinchar fuera es
   comparar el destino del clic, sin medir coordenadas.
   Ojo: la regla del display va en `.visor[open]`. Si se pusiera en `.visor`
   a secas, ganaría a la del navegador que oculta los <dialog> cerrados (los
   estilos de autor mandan sobre los del navegador) y el visor se quedaría
   siempre visible. */
.visor { border: none; background: none; padding: 0; }
.visor[open] {
  display: grid; place-items: center;
  inset: 0; margin: 0; width: 100vw; max-width: 100vw;
  height: 100dvh; max-height: 100dvh; overflow: hidden;
}
.visor::backdrop { background: rgba(20, 13, 7, .88); }
.visor img { max-width: 92vw; max-height: 92dvh; width: auto; height: auto; display: block; border-radius: 12px; background: var(--bg-2); }
.visor-x {
  position: fixed; top: 1.2rem; right: 1.4rem; width: 46px; height: 46px;
  border-radius: 999px; border: none; cursor: pointer; font-size: 1.6rem; line-height: 1;
  background: var(--surface); color: var(--primary);
}

/* CTA final de la galería (Lucía, 2026-08-10: "no aparece absolutamente
   nada... quiero que la frase se vea grande, en una línea, con buen
   contraste, y que el botón se intuya que hay que pulsarlo"). Antes llevaba
   la clase .reveal: si el observador de scroll no llegaba a dispararse por
   cualquier motivo, se quedaba en opacidad 0 para siempre — sin red de
   seguridad. Ahora se ve siempre, sin depender de ningún script, y encima
   de una tarjeta propia para que no se confunda con "fin de página". */
.galeria-cta {
  text-align: center; margin-top: 2.8rem; padding: 2.2rem 1.5rem;
  background: var(--bg-2); border-radius: 24px;
}
.galeria-cta p {
  color: var(--primary); margin-bottom: 1.3rem;
  font-family: 'Playfair Display', serif; font-weight: 600; font-style: italic;
  font-size: clamp(1.15rem, 2.6vw, 1.5rem); white-space: nowrap;
}
.galeria-cta .btn-primary { display: inline-flex; align-items: center; gap: .5rem; }
.galeria-cta .btn-primary svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round; transition: transform .2s;
}
.galeria-cta .btn-primary:hover svg { transform: translateX(3px); }
@media (max-width: 480px) {
  /* Con la frase más larga, a este ancho "en una línea" ya no cabe sin
     empequeñecer demasiado la letra — mejor dos líneas legibles que una
     apretada. */
  .galeria-cta p { white-space: normal; font-size: 1.05rem; }
}

/* ===== RESEÑAS PRO (estrellas + autor) ===== */
.resena .stars { color: var(--accent); letter-spacing: 2px; font-size: 1rem; margin-bottom: .7rem; }
.resena-head { display: flex; align-items: center; gap: .8rem; margin-top: 1.3rem; }
.resena-avatar { width: 44px; height: 44px; border-radius: 999px; background: var(--bg-2); display: grid; place-items: center; color: var(--accent); font-weight: 700; font-family: 'Playfair Display', serif; flex-shrink: 0; }
.resena-name { font-weight: 700; color: var(--ink); font-size: .95rem; line-height: 1.2; }
.resena-name span { display: block; font-weight: 400; color: var(--muted); font-size: .82rem; }

/* ===== Micro-animaciones de marca (elegantes, con respeto a reduced-motion) ===== */
@media (prefers-reduced-motion: no-preference) {
  .logo:hover .logo-mark, .hero-logo:hover .hero-logo-mark { animation: saluda .7s ease; }
  @keyframes saluda {
    0%, 100% { transform: rotate(0); }
    25% { transform: rotate(-14deg); }
    55% { transform: rotate(10deg); }
    80% { transform: rotate(-5deg); }
  }

  .float-btn { animation: latido 9s infinite; }
  .float-btn.ig { animation-delay: 3s; }
  .float-btn.mail { animation-delay: 6s; }
  @keyframes latido {
    0% { box-shadow: 0 10px 26px -8px rgba(20,33,60,.5), 0 0 0 0 var(--pulse); }
    5% { box-shadow: 0 10px 26px -8px rgba(20,33,60,.5), 0 0 0 4px var(--pulse); }
    13% { box-shadow: 0 10px 26px -8px rgba(20,33,60,.5), 0 0 0 15px var(--pulse-0); }
    100% { box-shadow: 0 10px 26px -8px rgba(20,33,60,.5), 0 0 0 0 var(--pulse-0); }
  }

}

/* ===== Portátiles bajos: ayuda puntual, ya no aplastar todo =====
   (hallmark audit, 2026-08-03) Esto eran 7 bloques por separado, acumulados
   sesión a sesión, que forzaban que cada sección cupiera entera de un
   vistazo (~637px útiles en un portátil de 14"). Con el header que ahora se
   esconde al bajar (ver header.nav-oculto y app.js) ya se recupera aire real
   sin aplastar nada, así que "cabe en una pantalla" deja de ser una regla
   dura: sigue siendo un buen objetivo por defecto, pero una sección puede
   pasar de un viewport si queda mejor resuelta así — no hace falta ver el
   título y todo el contenido a la vez. Solo quedan los ajustes que evitan
   overflow real en viewports muy bajos, con mucho más aire que antes. */
@media (min-width: 821px) and (max-height: 860px) {
  section { padding: clamp(2rem, 5.5vh, 7.5rem) 0; }
  .section-head { margin-bottom: clamp(1.25rem, 3vh, 4rem); }

  /* El titular de contacto es el más largo de la web y partía en dos líneas
     por el ancho de la cabecera, no por falta de sitio real. */
  #contacto .section-head { max-width: none; }
  #contacto .section-head p { max-width: 62ch; }
}

/* El titular a dos capas del inicio es más alto que el de una línea: se
   recupera un poco del relleno propio del hero para que no se salga. */
@media (min-width: 821px) and (max-height: 860px) {
  .hero:has(.hero-inicio) {
    --pad-b: clamp(.75rem, 1.8vh, 2.2rem);
    padding: clamp(.6rem, 1.6vh, 1.8rem) 0 var(--pad-b);
  }
}

/* ===== Ajustes de móvil =====
   Medido a 375x812. Nada de esto se aprecia en el ordenador, pero se sufre
   con el dedo. */

/* El punto sigue viéndose pequeño, pero la zona que responde al dedo pasa a
   34 px. El circulito se dibuja con ::after para no agrandarlo. */
.carrusel-punto {
  width: 34px; height: 34px;
  padding: 0; border: none; background: none;
  display: grid; place-items: center;
}
.carrusel-punto::after {
  content: '';
  width: 9px; height: 9px; border-radius: 999px;
  background: var(--line);
  transition: background .25s ease, width .25s ease;
}
.carrusel-punto[aria-current="true"] { background: none; width: 34px; }
.carrusel-punto[aria-current="true"]::after { background: var(--accent); width: 26px; }
.carrusel-puntos { gap: 0; }

@media (max-width: 820px) {
  /* El botón de menú medía 22x32: por debajo del mínimo cómodo de 44x44. */
  .menu-btn {
    width: 44px; height: 44px;
    display: grid; place-items: center;
    margin-right: -8px;   /* compensa el ancho extra para no descuadrar la barra */
  }
  .theme-toggle { width: 44px; height: 44px; }

  /* iOS hace zoom automático al tocar un campo con letra menor de 16 px, y
     luego deja la página descuadrada. A 16 px no lo hace. */
  #contacto input,
  #contacto textarea,
  #contacto select { font-size: 16px; }

  /* Enlaces del pie: más altos para el dedo, sin cambiar el aspecto. */
  .footer-legal a { display: inline-block; padding: .45rem .2rem; }
}
