/* =========================================================================
   Factoría Talleres Creativos — hoja de estilos
   Paleta y marca tomadas del sitio original (verde #5CBA9B, tinta #12110C)
   ========================================================================= */

/* ---------- Tokens ---------- */
:root {
  /* Marca */
  --verde: #5cba9b;
  --verde-hover: #4aa98a;
  /* Verde oscuro: el #5CBA9B no alcanza contraste AA como texto sobre blanco */
  --verde-texto: #10614b;
  --verde-suave: #eaf6f1;

  --tinta: #12110c;
  --tinta-70: #4a4842;
  --tinta-55: #6f6c64;

  --crema: #faf8f4;
  --blanco: #fff;
  --linea: #e6e2da;

  /* Tipografía */
  --display: "Fraunces", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --texto: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* Escala fluida */
  --t-xs: 0.8125rem;
  --t-sm: 0.9375rem;
  --t-base: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  --t-lg: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  --t-xl: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  --t-2xl: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  --t-3xl: clamp(2.25rem, 1.6rem + 3vw, 4rem);

  /* Espaciado y forma */
  --ancho: 1180px;
  --ancho-texto: 68ch;
  --gap: clamp(1rem, 0.7rem + 1.4vw, 2rem);
  --seccion: clamp(3.5rem, 2rem + 6vw, 7rem);
  --radio: 14px;
  --radio-lg: 22px;

  --sombra-sm: 0 1px 2px rgb(18 17 12 / 6%), 0 2px 8px rgb(18 17 12 / 4%);
  --sombra: 0 4px 12px rgb(18 17 12 / 7%), 0 16px 40px rgb(18 17 12 / 7%);

  --transicion: 180ms cubic-bezier(0.2, 0, 0.2, 1);
}

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  font-family: var(--texto);
  font-size: var(--t-base);
  line-height: 1.65;
  color: var(--tinta);
  background-color: #fbfaf7;
  /* Fondo infinito tipo papel plegado, pero difuso: grandes velos de luz y
     sombra muy suaves, sin líneas duras. Al ir fijo, el campo nunca se corta. */
  background-image:
    radial-gradient(120% 62% at 6% 12%, rgb(255 255 255 / 92%) 0%, transparent 62%),
    radial-gradient(95% 55% at 88% 4%, rgb(18 17 12 / 3.4%) 0%, transparent 66%),
    radial-gradient(140% 70% at 108% 46%, rgb(18 17 12 / 4.2%) 0%, transparent 60%),
    radial-gradient(120% 58% at -12% 62%, rgb(18 17 12 / 3.8%) 0%, transparent 62%),
    radial-gradient(150% 64% at 46% 118%, rgb(18 17 12 / 4.6%) 0%, transparent 58%),
    radial-gradient(90% 48% at 62% 74%, rgb(255 255 255 / 80%) 0%, transparent 64%),
    linear-gradient(168deg, rgb(255 255 255 / 55%) 0%, transparent 45%, rgb(18 17 12 / 2.6%) 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* En pantallas pequeñas el fondo acompaña el scroll: se escala al viewport y se
   repite, para que la composición se renueve en vez de estirarse una sola vez. */
@media (max-width: 720px) {
  body {
    background-attachment: scroll;
    background-size: 100vw 100vh;
    background-repeat: repeat;
  }
}

/* El atributo hidden lo aplica la hoja del navegador con [hidden]{display:none},
   y cualquier regla de autor que fije display la gana. Como varios componentes
   de aquí declaran display:grid o :flex, sin esta línea el hidden no oculta
   nada: el esqueleto de carga, el estado vacío y el aviso de error se verían
   los tres a la vez. */
[hidden] { display: none !important; }

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

button,
input,
select,
textarea { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

a { color: var(--verde-texto); text-underline-offset: 0.2em; }

:focus-visible {
  outline: 3px solid var(--verde-texto);
  outline-offset: 3px;
  border-radius: 4px;
}

/* El botón de play grande que iOS superpone cuando bloquea la reproducción
   automática. Los vídeos son decorativos y mudos: un control encima solo
   ensucia la foto. Si iOS no los arranca, se queda el poster, que es la misma
   imagen, y motion.js reintenta al primer gesto. */
/* Sin JavaScript no se añade la clase .motion, así que las reglas de
   posicionamiento de motion.css no aplican y el vídeo caería debajo de la
   foto en vez de encima. Se oculta: quedan las fotografías, que es la
   degradación correcta. */
html:not(.motion) [data-video] > video { display: none; }

[data-video] > video::-webkit-media-controls,
[data-video] > video::-webkit-media-controls-panel,
[data-video] > video::-webkit-media-controls-start-playback-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
}

@media (prefers-reduced-motion: reduce) {
  /* Los videos vienen en el HTML con autoplay. El JS los retira, pero si no
     llegara a ejecutarse esto los deja ocultos y se ve la foto de debajo. */
  [data-video] > video { display: none !important; }

  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- Los hijos de rejilla deben poder encogerse ----------
   Un hijo de grid o flex lleva min-width:auto por defecto, y eso le impide
   bajar de su contenido minimo. Una foto de 500px de ancho intrinseco
   convierte su columna en 500px aunque el telefono mida 371, y el ancho
   contagia al resto de la fila: en el hero llegaba a estirar el parrafo a
   531px, que .hero{overflow:hidden} recortaba en silencio, sin barra de
   scroll que delatara el problema.

   Es la causa del texto cortado y de las fotos recortadas en telefono. */
.hero__grid > *,
.hero__collage > figure,
.rejilla > *,
.rejilla--3 > *,
.mosaico > *,
.visita > *,
.franja > *,
.pie__grid > *,
.argumento > *,
.marcas__lista > li { min-width: 0; }
.burbujas > *,
.hero__datos > * { min-width: 0; }

/* Las imagenes tampoco deben imponer su ancho intrinseco a la columna */
.hero__collage img,
.tarjeta__media img,
.mosaico__item img,
.franja > img { min-width: 0; }

/* ---------- Utilidades ---------- */
.contenedor {
  width: min(100% - 2.5rem, var(--ancho));
  margin-inline: auto;
}

.solo-lectores {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.saltar {
  position: absolute;
  left: 50%;
  translate: -50% -150%;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--tinta);
  color: var(--blanco);
  border-radius: 0 0 var(--radio) var(--radio);
  text-decoration: none;
  transition: translate var(--transicion);
}
.saltar:focus { translate: -50% 0; }

/* ---------- Botones ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  padding: 0.8em 1.6em;
  border: 1.5px solid transparent;
  border-radius: 999px;
  font-family: var(--texto);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion),
              border-color var(--transicion), transform var(--transicion);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Texto tinta sobre verde: 9.4:1. El blanco sobre este verde no pasaría AA. */
.btn--primario { background: var(--verde); color: var(--tinta); }
.btn--primario:hover { background: var(--verde-hover); }

.btn--oscuro { background: var(--tinta); color: var(--blanco); }
.btn--oscuro:hover { background: #2b2921; }

.btn--linea { border-color: currentcolor; color: var(--tinta); }
.btn--linea:hover { background: var(--tinta); color: var(--blanco); border-color: var(--tinta); }

.btn--grande { padding: 1em 2em; font-size: var(--t-base); }

/* ---------- Barra de utilidad ---------- */
.utilidad {
  background: var(--tinta);
  color: #dedbd3;
  font-size: var(--t-xs);
}
.utilidad__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem 1.5rem;
  padding-block: 0.6rem;
}
.utilidad a { color: var(--blanco); text-decoration: none; }
.utilidad a:hover { text-decoration: underline; }
.utilidad__item { display: inline-flex; align-items: center; gap: 0.45em; }
.utilidad__item svg { width: 15px; height: 15px; flex: none; }

.estado { display: inline-flex; align-items: center; gap: 0.45em; font-weight: 600; }
.estado::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentcolor;
}
.estado--abierto { color: #79d6b4; }
.estado--cerrado { color: #f0a9a0; }

/* ---------- Cabecera ---------- */
.cabecera {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgb(255 255 255 / 88%);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--linea);
}
.cabecera__fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding-block: 0.9rem;
}
.cabecera__logo img { width: 168px; }

.nav__lista {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2rem);
  list-style: none;
  padding: 0;
}
.nav__lista a {
  position: relative;
  color: var(--tinta);
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  padding-block: 0.35rem;
}
.nav__lista a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--verde);
  scale: 0 1;
  transform-origin: left;
  transition: scale var(--transicion);
}
.nav__lista a:hover::after,
.nav__lista a[aria-current="page"]::after { scale: 1 1; }

/* Tienda destaca como acceso principal en todos los menús. */
.nav__lista a.nav__tienda {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.65rem 1.2rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--verde);
  color: var(--tinta);
  font-weight: 600;
  transition: background var(--transicion), transform var(--transicion);
}
.nav__lista a.nav__tienda::after { display: none; }
.nav__lista a.nav__tienda:hover { background: var(--verde-hover); transform: translateY(-2px); }
.nav__lista a.nav__tienda:active { transform: translateY(0); }
.nav__lista a.nav__tienda[aria-current="page"] { box-shadow: inset 0 0 0 2px var(--verde-texto); }

.cabecera__acciones { display: flex; align-items: center; gap: 0.75rem; }

.hamburguesa {
  display: none;
  width: 44px; height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--linea);
  border-radius: 10px;
  cursor: pointer;
}
.hamburguesa span {
  display: block;
  width: 20px; height: 2px;
  margin: 4px auto;
  background: var(--tinta);
  border-radius: 2px;
  transition: transform var(--transicion), opacity var(--transicion);
}
.hamburguesa[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.hamburguesa[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburguesa[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 880px) {
  .hamburguesa { display: block; }
  .cabecera__acciones .btn { display: none; }

  .nav {
    position: absolute;
    top: 100%; left: 0;
    width: 100%;
    background: var(--blanco);
    border-bottom: 1px solid var(--linea);
    box-shadow: var(--sombra);
    display: none;
  }
  .nav[data-abierto="true"] { display: block; }
  .nav__lista {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem 1.25rem 1.5rem;
  }
  .nav__lista li { border-bottom: 1px solid var(--linea); }
  .nav__lista a { display: block; padding: 0.95rem 0; font-size: var(--t-lg); }
  .nav__lista a::after { display: none; }
  .nav__lista a.nav__tienda { width: 100%; margin-block: 0.4rem; }
  .nav__cta { margin-top: 1.25rem; }
  .nav__cta .btn { width: 100%; }
}

@media (min-width: 881px) {
  .nav__cta { display: none; }
}

/* ---------- Secciones ---------- */
.seccion { padding-block: var(--seccion); }
.seccion--crema { background: rgb(250 248 244 / 82%); }
.seccion--verde { background: rgb(234 246 241 / 88%); }

.seccion__cabecera {
  max-width: var(--ancho-texto);
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}
.seccion__cabecera--centro {
  margin-inline: auto;
  text-align: center;
}
.etiqueta {
  display: inline-block;
  margin-bottom: 0.9rem;
  color: var(--verde-texto);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.seccion__titulo { font-size: var(--t-2xl); }
.seccion__intro {
  margin-top: 1rem;
  color: var(--tinta-70);
  font-size: var(--t-lg);
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding-block: clamp(3rem, 2rem + 6vw, 6.5rem);
  background:
    radial-gradient(ellipse 70% 90% at 15% 0%, rgb(234 246 241 / 78%), transparent 60%),
    radial-gradient(ellipse 60% 80% at 95% 20%, rgb(253 243 232 / 82%), transparent 65%);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  /* En movil es una sola columna. Sin declararla, la columna implicita es
     'auto' y la dimensiona el contenido: el collage la estiraba a 530px
     dentro de un telefono de 371, y .hero{overflow:hidden} lo recortaba
     en silencio, arrastrando tambien al parrafo y al titulo. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
}

.hero__insignia {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  margin-bottom: 1.5rem;
  padding: 0.45em 1em;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 999px;
  box-shadow: var(--sombra-sm);
  font-size: var(--t-xs);
  font-weight: 600;
}
.hero__insignia svg { width: 15px; height: 15px; color: var(--verde-texto); }

.hero__titulo {
  font-size: var(--t-3xl);
  font-weight: 600;
}
.hero__titulo em {
  font-style: italic;
  color: var(--verde-texto);
}
.hero__texto {
  max-width: 52ch;
  margin-top: 1.4rem;
  color: var(--tinta-70);
  font-size: var(--t-lg);
}
.hero__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2.2rem;
}
.hero__datos {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.5rem;
  margin-top: 2.75rem;
  padding-top: 2rem;
  border-top: 1px solid var(--linea);
  list-style: none;
  padding-inline: 0;
}
.hero__datos dt {
  color: var(--tinta-55);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.hero__datos dd {
  margin: 0.15rem 0 0;
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 600;
}

.hero__collage {
  display: grid;
  /* minmax(0,...) y no 1fr: una fraccion pelada no puede bajar del contenido
     minimo de sus hijos, y dos fotos de 500px de ancho intrinseco convertian
     estas columnas en 258px cada una dentro de un telefono de 371px. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem;
}
.hero__collage figure {
  margin: 0;
  border-radius: var(--radio-lg);
  overflow: hidden;
  background: var(--crema);
  box-shadow: var(--sombra);
}
.hero__collage img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Cuadrado en vez de 3:4: los vídeos del collage son 4:3, y en un marco
     vertical quedaban recortados a una franja central. El cuadrado deja
     ver el 75% del ancho en vez del 56%, sin volver la figura tan baja
     como un 4:3 puro. */
  aspect-ratio: 1 / 1;
}
.hero__collage figure:nth-child(1) { margin-top: 2rem; }
.hero__collage figure:nth-child(2) img { aspect-ratio: 1 / 1; }

/* ---------- Burbujas de intención del hero ---------- */
.hero__pregunta {
  margin-top: 2.4rem;
  color: var(--tinta-55);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.burbujas {
  display: grid;
  /* se apilan solas cuando la columna no da para dos: manda el ancho
     disponible, no el de la ventana */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 0.85rem;
  margin-top: 1rem;
  max-width: 36rem;
}
.burbuja {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 82px;
  padding: 0.9rem 0.9rem 0.9rem 1.6rem;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgb(18 17 12 / 5%);
  color: var(--tinta);
  text-decoration: none;
  transition: border-color var(--transicion), box-shadow var(--transicion),
              transform var(--transicion), background var(--transicion);
}
.burbuja:hover {
  background: var(--verde-suave);
  border-color: var(--verde);
  box-shadow: 0 6px 18px rgb(18 17 12 / 8%);
  transform: translateY(-2px);
}
.burbuja__texto { display: grid; gap: 0.1rem; min-width: 0; }
.burbuja__titulo {
  font-family: var(--display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.1;
}
.burbuja__desc {
  color: var(--tinta-55);
  font-size: var(--t-xs);
  line-height: 1.35;
  /* Sin text-wrap:nowrap. Impedir el salto de linea obliga a la burbuja a
     medir su contenido minimo (~286px), y dos burbujas asi imponen 572px de
     rejilla en un telefono de 390. Que envuelva en dos lineas no molesta. */
}
.burbuja__flecha {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  flex: none;
  border: 1px solid var(--linea);
  border-radius: 50%;
  color: var(--verde-texto);
  transition: background var(--transicion), border-color var(--transicion),
              color var(--transicion);
}
.burbuja:hover .burbuja__flecha {
  background: var(--verde);
  border-color: var(--verde);
  color: var(--tinta);
}
.burbuja__flecha svg {
  width: 17px; height: 17px;
  transition: translate var(--transicion);
}
.burbuja:hover .burbuja__flecha svg { translate: 2px 0; }

/* ---------- Índice de oferta del hero de talleres ----------
   Sin cajas, sin fondos y sin iconos: más abajo cada taller tiene su sección
   con foto y prosa, y dos bloques con fondo aquí competirían con ellas. El
   filete separa y el peso tipográfico jerarquiza; nada más. */
.oferta {
  display: grid;
  gap: 0;
  margin-top: 2.25rem;
  max-width: 44rem;
}
@media (min-width: 620px) {
  /* minmax(0,...) y no 1fr: una fracción pelada no puede encoger por debajo
     del contenido mínimo de sus hijos. Ya mordió dos veces en este proyecto. */
  .oferta { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 clamp(1.5rem, 4vw, 3rem); }
}

.oferta__grupo {
  padding-block: 1.1rem;
  border-top: 1px solid var(--linea);
}
/* En móvil van apilados, así que el último necesita cerrar con su filete.
   Desde 620px son dos columnas y el filete inferior sobraría. */
.oferta__grupo:last-child { border-bottom: 1px solid var(--linea); }
@media (min-width: 620px) {
  .oferta__grupo:last-child { border-bottom: 0; }
}

.oferta__titulo {
  margin-bottom: 0.5rem;
  font-family: var(--display);
  font-size: var(--t-lg);
  font-weight: 600;
}
/* El movimiento firma del sitio: Fraunces con la cursiva verde */
.oferta__titulo em {
  font-style: italic;
  color: var(--verde-texto);
}

.oferta__lista {
  display: grid;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--tinta-70);
  font-size: var(--t-base);
}
/* Una marca discreta en vez de la viñeta del navegador, que aquí se ve
   desalineada con la escala tipográfica del sitio. */
.oferta__lista li {
  display: flex;
  align-items: baseline;
  gap: 0.6em;
}
.oferta__lista li::before {
  content: "";
  flex: none;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--verde);
  translate: 0 -0.2em;
}

/* ---------- Marcas ---------- */
.marcas__lista {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  list-style: none;
  padding: 0;
}
.marcas__lista img {
  height: clamp(26px, 3.5vw, 38px);
  width: auto;
  filter: grayscale(1);
  opacity: 0.62;
  transition: filter var(--transicion), opacity var(--transicion);
}
.marcas__lista a:hover img,
.marcas__lista a:focus-visible img { filter: grayscale(0); opacity: 1; }

/* ---------- Rejillas de tarjetas ---------- */
.rejilla {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
}
.rejilla--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }

.tarjeta {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio-lg);
  overflow: hidden;
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.tarjeta:hover { transform: translateY(-4px); box-shadow: var(--sombra); }

.tarjeta__media {
  position: relative;
  background: var(--crema);
  overflow: hidden;
}
.tarjeta__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: scale 400ms cubic-bezier(0.2, 0, 0.2, 1);
}
.tarjeta:hover .tarjeta__media img { scale: 1.04; }
.tarjeta--taller .tarjeta__media img { aspect-ratio: 3 / 4; }

.tarjeta__cuerpo {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 0.6rem;
  padding: 1.4rem 1.5rem 1.6rem;
}
.tarjeta__titulo { font-size: var(--t-xl); }
.tarjeta__titulo a {
  color: inherit;
  text-decoration: none;
}
/* Enlace de tarjeta: toda la superficie es clicable, sin anidar enlaces */
.tarjeta__titulo a::after {
  content: "";
  position: absolute;
  inset: 0;
}
.tarjeta { position: relative; }

.tarjeta__texto {
  color: var(--tinta-70);
  font-size: var(--t-sm);
}
.tarjeta__pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: auto;
  padding-top: 1rem;
}
.tarjeta__meta {
  color: var(--tinta-55);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tarjeta__flecha {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--verde-texto);
  font-size: var(--t-sm);
  font-weight: 600;
}
.tarjeta__flecha svg { width: 16px; height: 16px; transition: translate var(--transicion); }
.tarjeta:hover .tarjeta__flecha svg { translate: 3px 0; }

/* Marco sin foto: para talleres de los que todavía no hay fotografía propia.
   Antes se usaba el flyer promocional, que arrastraba precios y fechas viejos. */
.marco-vacio {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: 1.5rem;
  text-align: center;
  background:
    repeating-linear-gradient(45deg, rgb(255 255 255 / 45%) 0 10px, transparent 10px 20px),
    linear-gradient(135deg, var(--verde-suave), #fdf3e8);
  color: var(--verde-texto);
}
.tarjeta--taller .marco-vacio { aspect-ratio: 3 / 4; }
.marco-vacio__nombre {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 600;
  line-height: 1.15;
}
.marco-vacio__nota {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--texto);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-55);
}

/* ---------- Separador entre talleres ----------
   Los fondos ya alternan, pero con secciones largas se pierde el hilo de
   dónde empieza cada taller. El filete va DENTRO del contenedor, no en el
   borde de la sección: así se alinea con el texto y con las fotos, y lee
   como el mismo lenguaje que .oferta y .argumento en el resto del sitio. */
.taller {
  padding-top: clamp(1.75rem, 4vw, 2.75rem);
  border-top: 1px solid var(--linea);
}

/* En móvil la foto abre el taller, siempre.
   .visita apila en el orden del HTML, y encuadernación tiene la prosa antes
   que la imagen a propósito: en escritorio su foto va a la derecha, que es
   la alternancia que le da ritmo a la página. Ese mismo orden en una sola
   columna dejaba la foto debajo del botón, ya fuera del taller que ilustra.
   Se corrige con order, sin tocar el HTML ni perder la alternancia. */
@media (max-width: 859px) {
  .taller__foto { order: -1; }
}

/* Foto de una sección de taller: proporción fija para que no domine en móvil */
.foto-taller {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-sm);
}

/* Franja de comunidad */
.franja {
  display: grid;
  gap: var(--gap);
  align-items: center;
}
@media (min-width: 860px) {
  .franja { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}
.franja img {
  width: 100%;
  height: auto;
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra);
}

.chip {
  position: absolute;
  top: 0.9rem; left: 0.9rem;
  z-index: 1;
  padding: 0.35em 0.8em;
  background: var(--blanco);
  border-radius: 999px;
  box-shadow: var(--sombra-sm);
  font-size: var(--t-xs);
  font-weight: 700;
}

/* ---------- Bloques de valor ---------- */
.valor {
  display: grid;
  gap: 0.85rem;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio-lg);
}
.valor__icono {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  background: var(--verde-suave);
  border-radius: 12px;
  color: var(--verde-texto);
}
.valor__icono svg { width: 22px; height: 22px; }
.valor h3 { font-size: var(--t-lg); }
.valor p { color: var(--tinta-70); font-size: var(--t-sm); }

/* ---------- Argumentos ----------
   Reemplaza a las tres tarjetas iguales de icono+título+texto. Nada nuevo
   en el sistema: Fraunces, la cursiva verde del hero, el filete --linea y
   la escala de tipo que ya existían. Lo que cambia es dónde se aplican.

   .valor sigue vivo: lo usa cricut.html. */
.argumentos {
  display: grid;
  /* Los filetes hacen de separador: sin hueco entre filas, el borde
     superior de cada una traza la línea. */
  gap: 0;
}
.argumento {
  display: grid;
  gap: 0.6rem;
  padding-block: clamp(1.75rem, 4vw, 2.75rem);
  border-top: 1px solid var(--linea);
}
.argumento:last-child { border-bottom: 1px solid var(--linea); }

/* Desde 860px la fila se parte en dos columnas desiguales: el enunciado a
   la izquierda, el desarrollo a la derecha. La asimetría es lo que evita
   que vuelva a leerse como tres celdas iguales. */
@media (min-width: 860px) {
  .argumento {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: 0 clamp(2rem, 5vw, 4.5rem);
    align-items: start;
  }
}

.argumento__titulo {
  font-size: var(--t-2xl);
  font-weight: 600;
  text-wrap: balance;
}
/* El movimiento firma del sitio, que hasta ahora solo usaba el hero */
.argumento__titulo em {
  font-style: italic;
  color: var(--verde-texto);
}
.argumento__texto {
  max-width: 46ch;
  color: var(--tinta-70);
  /* Sube de --t-sm a --t-lg: el cambio de densidad es la mitad del efecto */
  font-size: var(--t-lg);
}

/* ---------- Testimonios ---------- */
.testimonio {
  display: grid;
  gap: 1.25rem;
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio-lg);
}
.testimonio blockquote {
  margin: 0;
  font-family: var(--display);
  font-size: var(--t-lg);
  line-height: 1.4;
}
.testimonio figcaption {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}
.testimonio img {
  width: 54px; height: 54px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
}
.testimonio__quien { font-weight: 600; font-size: var(--t-sm); }
.testimonio__que { color: var(--tinta-55); font-size: var(--t-xs); }

/* ---------- Texto largo ---------- */
.prosa { max-width: var(--ancho-texto); }
.prosa > * + * { margin-top: 1.1em; }
.prosa h2 { margin-top: 2.2em; font-size: var(--t-2xl); }
.prosa h3 { margin-top: 1.8em; font-size: var(--t-xl); }
.prosa ul { padding-left: 1.3em; }
.prosa li + li { margin-top: 0.4em; }
.prosa strong { font-weight: 650; }

/* ---------- Visitanos ---------- */
.visita {
  display: grid;
  gap: var(--gap);
  align-items: start;
}
@media (min-width: 860px) {
  .visita { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}
.mapa {
  border: 0;
  width: 100%;
  aspect-ratio: 16 / 11;
  border-radius: var(--radio-lg);
  box-shadow: var(--sombra-sm);
}
.horario {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}
.horario caption {
  padding-bottom: 0.9rem;
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 600;
  text-align: left;
}
.horario th,
.horario td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--linea);
}
.horario th { font-weight: 500; }
.horario td { text-align: right; font-variant-numeric: tabular-nums; }
.horario tr[data-hoy="true"] {
  background: var(--verde-suave);
  font-weight: 700;
}
.horario tr[data-hoy="true"] th::after {
  content: " · hoy";
  color: var(--verde-texto);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.direccion {
  display: grid;
  gap: 1.1rem;
  margin-top: 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
}
.direccion__item { display: flex; gap: 0.8rem; }
.direccion__item svg {
  width: 19px; height: 19px;
  flex: none;
  margin-top: 0.25em;
  color: var(--verde-texto);
}
.direccion__item a { font-weight: 600; }

/* ---------- Llamada final ---------- */
.cierre {
  padding-block: var(--seccion);
  background: var(--tinta);
  color: var(--blanco);
  text-align: center;
}
.cierre h2 { font-size: var(--t-2xl); }
.cierre p {
  max-width: 54ch;
  margin: 1rem auto 0;
  color: #c9c6be;
  font-size: var(--t-lg);
}
.cierre__acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.85rem;
  margin-top: 2.25rem;
}
.cierre .btn--linea { color: var(--blanco); }
.cierre .btn--linea:hover { background: var(--blanco); color: var(--tinta); border-color: var(--blanco); }

/* ---------- Formulario ---------- */
.formulario {
  display: grid;
  gap: 1.25rem;
  max-width: 620px;
}
.campo { display: grid; gap: 0.4rem; }
.campo label { font-size: var(--t-sm); font-weight: 600; }
.campo .req { color: #b3261e; }
.campo input,
.campo textarea,
.campo select {
  padding: 0.8rem 1rem;
  background: var(--blanco);
  border: 1.5px solid var(--linea);
  border-radius: 10px;
  transition: border-color var(--transicion);
}
.campo input:focus,
.campo textarea:focus,
.campo select:focus { border-color: var(--verde-texto); }
.campo textarea { min-height: 150px; resize: vertical; }
.campo__ayuda { color: var(--tinta-55); font-size: var(--t-xs); }

.consentimiento {
  display: flex;
  gap: 0.75rem;
  align-items: start;
  padding: 1rem 1.2rem;
  background: var(--crema);
  border-radius: 12px;
  font-size: var(--t-sm);
}
.consentimiento input { margin-top: 0.3em; width: 18px; height: 18px; flex: none; }

/* ---------- Pie ---------- */
.pie {
  padding-block: clamp(3rem, 5vw, 4.5rem) 2rem;
  background: rgb(250 248 244 / 82%);
  border-top: 1px solid var(--linea);
}
.pie__grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}
.pie__logo img { width: 190px; margin-bottom: 1.1rem; }
.pie__lema { max-width: 34ch; color: var(--tinta-70); font-size: var(--t-sm); }
.pie h2 {
  margin-bottom: 1.1rem;
  font-family: var(--texto);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tinta-55);
}
.pie ul { list-style: none; padding: 0; display: grid; gap: 0.6rem; }
.pie a { color: var(--tinta); font-size: var(--t-sm); text-decoration: none; }
.pie a:hover { color: var(--verde-texto); text-decoration: underline; }

.redes { display: flex; gap: 0.6rem; margin-top: 1.4rem; }
.redes a {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: 50%;
  transition: background var(--transicion), color var(--transicion), transform var(--transicion);
}
.redes a:hover { background: var(--tinta); color: var(--blanco); transform: translateY(-2px); }
.redes svg { width: 19px; height: 19px; }

.pie__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
  color: var(--tinta-55);
  font-size: var(--t-xs);
}
.pie__legal ul { display: flex; flex-wrap: wrap; gap: 1.25rem; }

/* ---------- Botón flotante de WhatsApp ---------- */
.flotante {
  position: fixed;
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: clamp(1rem, 3vw, 1.75rem);
  z-index: 90;
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.85em 1.35em;
  background: #25d366;
  color: #06301a;
  border-radius: 999px;
  box-shadow: 0 6px 20px rgb(18 17 12 / 22%);
  font-size: var(--t-sm);
  font-weight: 700;
  text-decoration: none;
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.flotante:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgb(18 17 12 / 28%); }
.flotante svg { width: 21px; height: 21px; }
@media (max-width: 520px) {
  .flotante__texto { display: none; }
  .flotante { padding: 0.95em; }
}

/* ---------- Aparición al hacer scroll ---------- */
@media (prefers-reduced-motion: no-preference) {
  .revelar {
    opacity: 0;
    translate: 0 18px;
    transition: opacity 550ms ease, translate 550ms cubic-bezier(0.2, 0, 0.2, 1);
  }
  .revelar[data-visible="true"] { opacity: 1; translate: 0 0; }
}

/* ---------- Banda inmersiva ----------
   Imagen a todo el ancho con velo oscuro; sirve de respiro entre bloques
   de tarjetas y da ambiente de tienda. */
.banda {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(340px, 44vw, 480px);
  overflow: hidden;
  text-align: center;
  color: var(--blanco);
}
.banda > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Velo: sube el contraste del texto por encima de AA sobre cualquier foto */
.banda::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(rgb(18 17 12 / 66%), rgb(18 17 12 / 78%));
}
.banda__contenido {
  position: relative;
  z-index: 1;
  max-width: 58ch;
  padding: clamp(2.5rem, 6vw, 4rem) 1.5rem;
}
.banda__contenido .etiqueta { color: #b8ecd8; }
.banda h2 { font-size: var(--t-2xl); }
.banda p {
  margin-top: 1rem;
  color: #eceae5;
  font-size: var(--t-lg);
}
.banda .hero__acciones { justify-content: center; }
.banda .btn--linea { color: var(--blanco); }
.banda .btn--linea:hover { background: var(--blanco); color: var(--tinta); border-color: var(--blanco); }

/* ---------- Mosaico de categorías ----------
   Tarjeta que es toda imagen, con el rótulo encima. */
.mosaico {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
}
.mosaico__item {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(260px, 30vw, 340px);
  border-radius: var(--radio-lg);
  overflow: hidden;
  isolation: isolate;
}
.mosaico__item img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 500ms cubic-bezier(0.2, 0, 0.2, 1);
}
.mosaico__item::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Denso donde se apoya el texto: por debajo de esto el párrafo no llega a AA */
  background: linear-gradient(
    to top,
    rgb(18 17 12 / 92%) 0%,
    rgb(18 17 12 / 80%) 50%,
    rgb(18 17 12 / 45%) 72%,
    rgb(18 17 12 / 5%) 100%
  );
}
.mosaico__item:hover img,
.mosaico__item:focus-within img { scale: 1.06; }

.mosaico__texto { padding: clamp(1.25rem, 3vw, 1.75rem); color: var(--blanco); }
.mosaico__texto h3 { font-size: var(--t-xl); }
.mosaico__texto p {
  margin-top: 0.4rem;
  color: #e6e3dc;
  font-size: var(--t-sm);
}
.mosaico__texto a {
  color: var(--blanco);
  text-decoration: none;
}
.mosaico__texto a::after {
  content: "";
  position: absolute;
  inset: 0;
}
.mosaico__enlace {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  margin-top: 0.9rem;
  font-size: var(--t-sm);
  font-weight: 600;
  color: #b8ecd8;
}
.mosaico__enlace svg { width: 16px; height: 16px; transition: translate var(--transicion); }
.mosaico__item:hover .mosaico__enlace svg { translate: 3px 0; }

/* ---------- Estados de error del formulario ----------
   Validación propia en vez de los globos nativos del navegador: se leen
   mal, no se pueden estilar y desaparecen solos. El mensaje vive junto al
   campo, se anuncia por aria-live y el borde refuerza en rojo. */
.campo__error {
  display: none;
  align-items: center;
  gap: 0.4em;
  /* #b3261e sobre blanco da 5.9:1 — pasa AA para texto pequeño */
  color: #b3261e;
  font-size: var(--t-xs);
  font-weight: 600;
}
/* Punto rojo como marca: el color nunca es el único indicador, porque el
   mensaje de texto va al lado y el campo lleva aria-invalid. */
.campo__error::before {
  content: "";
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentcolor;
}
.campo__error[data-visible] { display: flex; }

.campo :is(input, textarea, select)[aria-invalid="true"] {
  border-color: #b3261e;
  background: #fdf7f6;
}
.campo :is(input, textarea, select)[aria-invalid="true"]:focus {
  border-color: #b3261e;
  outline-color: #b3261e;
}

/* Consentimiento sin marcar: el bloque entero se señala, no solo la casilla */
.consentimiento[data-invalido] {
  background: #fdf7f6;
  box-shadow: inset 0 0 0 1.5px #b3261e;
}

/* Aviso a nivel de formulario. Cuenta cuántos campos faltan, para que quien
   use lector de pantalla sepa el alcance antes de recorrer el formulario. */
.formulario__aviso {
  display: none;
  gap: 0.5em;
  padding: 0.9rem 1.1rem;
  border-radius: 10px;
  background: #fdf7f6;
  box-shadow: inset 0 0 0 1.5px #b3261e;
  color: #8c1d18;
  font-size: var(--t-sm);
  font-weight: 600;
}
.formulario__aviso[data-visible] { display: flex; }

/* ---------- Estado de carga ----------
   El texto cambia a "Enviando…", así que con "reducir movimiento" activado
   (que congela el giro) el estado sigue siendo legible sin depender del giro. */
.btn[data-cargando] {
  position: relative;
  pointer-events: none;
  opacity: 0.72;
}
.btn[data-cargando]::before {
  content: "";
  width: 1em; height: 1em;
  flex: none;
  border: 2px solid currentcolor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: girar 620ms linear infinite;
}
@keyframes girar {
  to { transform: rotate(360deg); }
}

/* ═══════════════════════════════════════════════════════════════════════
   Widget de la tienda (SpreadSimple)
   La tienda la sirve un widget de terceros con su propio diseño. Aquí solo
   se le da sitio dentro de la página y un estado de carga, para que no haya
   un salto en blanco mientras baja su bundle.
   ═══════════════════════════════════════════════════════════════════════ */
.seccion--tienda { padding-block: clamp(1.5rem, 4vw, 3rem); }

.tienda-widget { min-height: 60vh; }

.tienda-widget__cargando {
  display: grid;
  place-items: center;
  gap: 0.85rem;
  min-height: 60vh;
  color: var(--tinta-55);
  font-size: 0.95rem;
}
.tienda-widget__spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid var(--linea);
  border-top-color: var(--verde);
  animation: tienda-giro 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .tienda-widget__spinner { animation-duration: 2s; }
}
@keyframes tienda-giro { to { transform: rotate(360deg); } }

/* Cuando el widget ya pintó, su propio contenido reemplaza el div: si deja
   algo, que no arrastre el min-height del estado de carga. */
.tienda-widget:not(:has(.tienda-widget__cargando)) { min-height: 0; }

/* ==========================================================================
   Aire muerto — 12-sep-2026
   Medido en vivo a 1920px antes de tocar nada. No son decisiones de ritmo:
   son márgenes que separan de algo que no está.
   ========================================================================== */

/* 1. El primer hijo de un bloque de prosa no tiene nada arriba de lo que
      separarse. `.prosa h2` lleva margin-top: 2.2em para despegarse del
      párrafo anterior, y en el primer h2 de la sección eso son 88px de vacío
      contra el padding de la sección. En cricut era la mitad del hueco. */
.prosa > :first-child,
.seccion__cabecera > :first-child { margin-top: 0; }

/* 2. Hero que termina en su cabecera (talleres, nosotros, contacto, tienda).
      Ahí se apilan tres separadores donde hace falta uno:
        .hero              padding-bottom   104px
        .seccion__cabecera margin-bottom     52px  <- muerto: es el ultimo hijo
        .seccion           padding-top      112px
      Total medido: 268px. El :has() es lo que mantiene esto acotado — el hero
      de la portada y el de cricut llevan collage debajo, no cabecera, así que
      no entran aquí y conservan su aire, que ahí sí sostiene contenido. */
.hero > .contenedor > .seccion__cabecera:last-child { margin-bottom: 0; }

/*    El pie del hero y la cabeza de la seccion siguiente van por .compacta,
      NO por :has(). Probé con :has() y rompía la tienda: ese selector suma la
      especificidad de su argumento (.seccion__cabecera:last-child), le ganaba
      a la regla de tienda.css y devolvía aquel hueco de 28px a 84px. Con la
      clase, el alcance es exactamente el pedido y tienda.css sigue mandando
      en la suya. */

/* 3. Ritmo entre secciones, solo en las páginas que lo piden por su <body>.
      var(--seccion) tope en 7rem: a 1920px son 112px arriba y 112 abajo, o
      sea 224px idénticos entre cada par de secciones. El ancho del texto
      está topado en --ancho-texto y no crece con la pantalla, pero el aire
      vertical sí, y por eso se dispara en monitores grandes.
      Va por clase y no tocando --seccion porque ese token lo comparten
      Inicio y Tienda, y ahí no se pidió el cambio. */
.compacta .seccion,
.compacta .cierre { padding-block: clamp(2.5rem, 1.5rem + 3vw, 4.5rem); }

/* 4. Pie del hero y cabeza de la seccion siguiente, en las cuatro paginas.
      Cubre por igual el hero que termina en cabecera (talleres, nosotros,
      contacto) y el de cricut, que lleva collage y dejaba una banda vacia de
      ancho completo de 176px hasta el primer titular. La portada no lleva la
      clase, asi que conserva su aire. */
.compacta .hero { padding-bottom: clamp(2rem, 3vw, 3rem); }
.compacta .hero + .seccion { padding-top: clamp(2rem, 3vw, 3rem); }
