/*
  Componentes visuales (Tarea 6). El marcado está en parts/ (abanico, puertas, azulejo, marcas, resenas, urgencias y
  horario) y los pide el contenido con atajos: [ole_abanico], [ole_puertas], [ole_urgencias], [ole_resenas],
  [ole_marcas] y [ole_horario] (inc/wp/atajos.php). El azulejo lo pinta siempre el pie. Se carga después de la carcasa. Al final
  va el formulario de cita (Tarea 9: [ole_formulario_cita], con su botón [ole_cita_cta], que usa .btn).

  Lo copiado del planteamiento (planteamiento/index.html): .abanico y .petalo (con las mismas animaciones, repartidas entre el pétalo y su
  <svg> desde la Tarea 16a: ver el comentario de @keyframes abrir), .puerta (con
  su pétalo y su gancho), .baldosa (con el pétalo en una máscara SVG en lugar de un <svg> por baldosa: el HTML pesa unos
  18 KB menos) y el enfoque de titulares (.enfoca y .visto, que pone ole.js).

  El pétalo. Es el del logo (assets/img/logo-ole-optica.svg): una elipse estrecha, de 14 x 41,13 (ancho entre alto, 0,34). El
  abanico es la marca del logo ampliada, con sus cuatro elipses en su sitio y con sus ángulos; las puertas, las urgencias y el
  héroe de las páginas interiores pintan una elipse (ole_petalo_svg) y la máscara del azulejo, otra, con su base en la esquina.
  La geometría vive en inc/logica/componentes.php (OLE_PETALOS): el abanico la recibe en línea desde parts/abanico.php y la
  máscara del azulejo repite rx y ry (una prueba vigila que coincidan con las del logo).

  Botones: .btn (azul, el principal) y .btn--claro (de contorno). Los usan las urgencias y los usarán el héroe de la
  portada y la cita de las tareas siguientes. Los de la carcasa llevan clases propias (.cabecera__cta, .barra-movil__*).

  Colores. Sol y Lima, siempre con texto oscuro: cada puerta define --c (el color de su pétalo) y --on (el texto sobre
  ese color: blanco sobre el azul, tinta sobre lima y sol). --ink3 no se usa en texto pequeño (3,7:1): el texto va en
  --ink o --ink2. Foco: las superficies de color fijan --foco: var(--ink), que se ve sobre ellas (base.css lo lee).

  Movimiento. Cada animación es un fenómeno óptico real (DESIGN.md §6): la superposición del abanico y el enfoque de
  los titulares. Con prefers-reduced-motion: reduce, todo quieto: sin animación en los pétalos, sin transición en el
  abanico y titulares nítidos. El estado de las puertas (color al pasar el ratón) sigue cambiando, sin transición.

  Lo que solo vale con JavaScript cuelga de la clase js de <html> (la pone un fragmento del <head>): sin ella, los
  titulares .enfoca se ven nítidos.
*/

/* ---------------------------------------------------------- botones */
.btn {
  --foco: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: .6em 26px;                 /* el alto de arriba y abajo no cambia un botón de una línea (lo da min-height) y deja aire si el texto se parte */
  border: 0;
  border-radius: 999px;
  background: var(--azul);
  color: #fff;
  font: 700 1rem/1.2 var(--f);
  overflow-wrap: anywhere;            /* con la letra al 200 % a 320 px, una palabra larga («Vägbeskrivning») se parte en vez de salirse del botón */
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background .2s, color .2s;
}

/* Al pasar el ratón, la mezcla azul + buganvilla (como el botón de la cabecera). */
.btn:hover {
  background: var(--m-ab);
}

.btn--claro {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}

.btn--claro:hover {
  background: var(--ink);
  color: #fff;
}

/* ---------------------------------------------------------- el abanico de pétalos */
/* La marca del logo ampliada. parts/abanico.php lleva a cada .petalo, en línea y sacados de OLE_PETALOS, dónde está su base (--x e
   --y, en % de .abanico__marca), su ángulo (--a) y su color (--c); a .abanico__marca, su proporción (aspect-ratio, la de la caja que
   envuelve a los cuatro pétalos del logo) y --ancho-petalo, lo que mide cada pétalo de ancho en % de la marca. Aquí no hay números
   de la geometría: cada pétalo se coloca derecho con su base en (--x, --y) y gira --a sobre ella, y queda como en el logo. */
.abanico {
  position: relative;
  display: flex;                      /* la marca, centrada en la caja */
  align-items: center;
  justify-content: center;
  width: min(560px, 100%);
  aspect-ratio: 10 / 7.4;
  margin-left: auto;
  isolation: isolate;                 /* los pétalos se mezclan entre sí, no con la página */
  rotate: var(--inclina, 0deg);       /* ole.js lo inclina hacia el puntero fino */
  transition: rotate .9s cubic-bezier(.2, .7, .2, 1);
}

/* La marca mide tres cuartos del ancho de la caja y queda centrada: ocupa el 80 % de su alto y deja el 12,5 % de su ancho a cada
   lado y el 10 % de su alto por arriba y por abajo, aire de sobra para lo que se abre al respirar y se inclina. */
.abanico__marca {
  position: relative;
  flex: none;
  width: 75%;
}

.petalo {
  position: absolute;
  bottom: calc(100% - var(--y));                          /* la base, el centro del borde de abajo, en (--x, --y) */
  left: calc(var(--x) - var(--ancho-petalo) / 2);
  width: var(--ancho-petalo);                             /* la misma elipse en los cuatro: sin escalas por pétalo */
  transform-origin: 50% 100%;                             /* gira sobre su base */
  rotate: var(--a);
  color: var(--c);
  mix-blend-mode: multiply;           /* donde se cruzan sale el color de la mezcla */
  --retraso: 0s;                      /* cuánto tarda en empezar a abrirse: cada pétalo, un poco después del anterior (abajo) */
  animation: abrir 1.7s cubic-bezier(.16, .8, .2, 1) var(--retraso) both, respirar 3s calc(1.7s + var(--retraso)) ease-in-out;
}

.petalo svg {
  display: block;
  width: 100%;
  height: auto;                       /* su alto sale del viewBox de la elipse (ole_petalo_svg) */
  overflow: visible;
  fill: currentColor;
  transform-origin: 50% 100%;         /* gira sobre la misma base que el pétalo: la suma de los dos giros es un solo giro sobre ella */
  animation: girar 1.7s cubic-bezier(.16, .8, .2, 1) var(--retraso) both;
}

/* El orden del logo, de izquierda a derecha: lima, azul, sol y buganvilla; cada uno empieza un poco después del anterior. */
.petalo:nth-child(2) { --retraso: .08s; }
.petalo:nth-child(3) { --retraso: .16s; }
.petalo:nth-child(4) { --retraso: .24s; }

/* Cada pétalo lleva tres animaciones, repartidas para que ninguna estorbe a otra. La apertura (abrir: el pétalo sale del desenfoque y de la
   transparencia; girar: su <svg> pasa de estar girado al revés a estar derecho, así que la suma con el ángulo --a del pétalo va de 0 a --a) y,
   cuando acaba, la respiración (respirar: el ángulo --a crece un 12 % y vuelve, una sola vez; empieza 1,7 s después, cuando acaba su apertura).
   Lo que se mueve solo dura 5 s como mucho (WCAG 2.2.2, como las demos; 18-oct): el último pétalo empieza a los 0,24 s, se abre en 1,7 s y
   respira en 3 s, así que todo queda quieto a los 4,94 s.
   Antes, la apertura también giraba la propiedad rotate del pétalo y chocaba con la respiración, que gira esa misma propiedad: Chrome no pasaba
   ninguna de las dos al compositor y las resolvía en cada fotograma en el hilo principal. Medido con la CPU a la cuarta parte, el hilo principal
   estaba ocupado de 0,8 a 1,8 s de cada 4 s de reposo, siempre, con el abanico abierto y aunque ya no se viera (en un móvil, batería y respuesta
   al tacto). Con el giro de la apertura en el <svg> y en transform, queda en 10 ms. Hace falta que el pétalo tenga a la vez la apertura (su
   filtro y su opacidad se quedan en el pétalo): una respiración con retraso sola, o con otra animación de rotate delante, vuelve al hilo principal. */
@keyframes abrir {
  from { filter: blur(18px); opacity: 0; }
  to { filter: blur(0); opacity: 1; }
}

@keyframes girar {
  from { transform: rotate(calc(var(--a) * -1)); }
  to { transform: rotate(0deg); }
}

@keyframes respirar {
  0%, 100% { rotate: var(--a); }
  50% { rotate: calc(var(--a) * 1.12); }
}

/* Las lentes que se tocan (assets/js/lentes.js, 18-oct).
   - Cada pétalo se arrastra (--dx, --dy), se gira (--giro) y se balancea mientras se mueve (--balanceo).
   - Solo la elipse recoge el puntero, no las esquinas de la caja del pétalo.
   - El pétalo que ya se ha tocado deja de respirar y se queda donde lo dejen. */
.petalo {
  translate: var(--dx, 0px) var(--dy, 0px);
}

.abanico--vivo .petalo,
.abanico--vivo .petalo svg {
  pointer-events: none;
}

.abanico--vivo .petalo ellipse {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;                 /* con el dedo, arrastrar la lente no desplaza la página */
}

.abanico--vivo .petalo--arrastrando ellipse {
  cursor: grabbing;
}

.petalo--libre {
  animation: none;
  rotate: calc(var(--a) + var(--giro, 0deg) + var(--balanceo, 0deg));
  transition: rotate .35s cubic-bezier(.2, .8, .2, 1), scale .2s ease;
}

.petalo--arrastrando {
  scale: 1.05;
  transition: rotate .12s linear, scale .2s ease;
}

.abanico--volviendo .petalo {
  transition: translate .8s cubic-bezier(.2, .8, .2, 1), rotate .8s cubic-bezier(.2, .8, .2, 1);
}

.abanico--tocado .petalo:focus-visible {
  transition: translate .18s ease-out, rotate .3s ease;   /* con el teclado, cada paso se ve suave */
}

/* El foco del teclado: un anillo de tinta que sigue la elipse. */
.petalo:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 50%;
}

/* Mientras se juega, el abanico no se inclina hacia el puntero (ole.js): la lente tiene que ir justo debajo del dedo. */
.abanico.abanico--tocado {
  rotate: 0deg;
}

/* La pista, debajo de la marca, con una mano que arrastra. Aparece cuando termina la apertura y se va al tocar una lente;
   en su sitio sale «Volver al logo». */
.abanico__pista,
.abanico__volver {
  position: absolute;
  left: 50%;
  bottom: 0;
  translate: -50% 0;
  width: max-content;
  max-width: 100%;                    /* en alemán, con la letra grande o en un móvil estrecho, se parte en dos líneas y no se sale */
  margin: 0;
  font: 600 .8125rem/1.2 var(--f);
  letter-spacing: .01em;
  text-align: center;
}

.abanico__pista[hidden],
.abanico__volver[hidden] {
  display: none;                      /* el display de abajo pisaría al de [hidden]: sin JavaScript no se ven */
}

.abanico__pista {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  color: var(--ink2);
  animation: pista-entra .6s ease 1.9s both;
  transition: opacity .3s ease;
}

.abanico--tocado .abanico__pista {
  opacity: 0;
  visibility: hidden;
}

.abanico__mano {
  width: 1.35em;
  height: 1.35em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 11V5.5a1.5 1.5 0 0 1 3 0V10h.6V8.6a1.5 1.5 0 0 1 3 0V10h.6V9.4a1.5 1.5 0 0 1 3 0V15a6 6 0 0 1-6 6h-1.3a5 5 0 0 1-3.9-1.9L4.6 15.5a1.4 1.4 0 0 1 2-2L9 15.6z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 11V5.5a1.5 1.5 0 0 1 3 0V10h.6V8.6a1.5 1.5 0 0 1 3 0V10h.6V9.4a1.5 1.5 0 0 1 3 0V15a6 6 0 0 1-6 6h-1.3a5 5 0 0 1-3.9-1.9L4.6 15.5a1.4 1.4 0 0 1 2-2L9 15.6z'/%3E%3C/svg%3E") center / contain no-repeat;
  animation: mano 1.2s ease-in-out 2.6s 2;   /* dos empujones y quieta a los 5 s (WCAG 2.2.2) */
}

.abanico__volver {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  padding: .6em 1.05em;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: var(--cal);
  color: var(--ink);
  cursor: pointer;
}

.abanico__volver::before {
  content: "↺";
  font-size: 1.15em;
  line-height: 1;
}

@media (hover: hover) {
  .abanico__volver:hover {
    background: var(--ink);
    color: var(--cal);
  }
}

.abanico__volver:focus-visible {
  outline: 3px solid var(--azul);
  outline-offset: 3px;
}

@keyframes pista-entra {
  from { opacity: 0; translate: -50% 6px; }
  to { opacity: 1; translate: -50% 0; }
}

@keyframes mano {
  0%, 100% { translate: 0 0; }
  50% { translate: 7px -2px; }
}

@media (prefers-reduced-motion: reduce) {
  .abanico__pista,
  .abanico__mano {
    animation: none;
  }

  .petalo--libre,
  .petalo--arrastrando,
  .abanico--volviendo .petalo,
  .abanico--tocado .petalo:focus-visible {
    transition: none;
  }
}

@media (max-width: 800px) {
  .abanico {
    width: min(400px, 92%);
    margin: 0 auto;
  }
}

/* ---------------------------------------------------------- iconos de los titulares (18-oct) */
/* inc/wp/iconos.php mete el icono (span.simbolo) delante del texto de los titulares con «con-icono icono-{nombre}». Es un dibujo de línea en
   tinta sobre dos lentes redondas de color que se cruzan (multiply), con colores distintos en cada icono. Al entrar en pantalla
   (.visto) las dos lentes se juntan y el dibujo se anima una vez; al pasar el ratón, otra vez. */
.con-icono {
  display: flex;
  flex-wrap: wrap;                    /* si el titular no cabe al lado del icono (320 px con la letra al 200 %), baja debajo de él */
  overflow-wrap: anywhere;            /* el texto es un elemento flex anónimo: con break-word, «Skandinavischer» no se partía y desbordaba */
  align-items: center;
  gap: 12px 16px;
}

.simbolo {
  --i1: var(--azul);
  --i2: var(--lima);
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 84px;
  height: 72px;
  isolation: isolate;
}

.simbolo::before,
.simbolo::after {
  content: "";
  position: absolute;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  mix-blend-mode: multiply;
}

.simbolo::before {
  top: 0;
  left: 0;
  background: color-mix(in srgb, var(--i1) 32%, #fff);
}

.simbolo::after {
  right: 0;
  bottom: 0;
  background: color-mix(in srgb, var(--i2) 38%, #fff);
}

.simbolo svg {
  position: relative;
  z-index: 1;
  width: 34px;
  height: 34px;
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.simbolo .simbolo__punto {
  fill: var(--ink);
  stroke: none;
}

.simbolo__aguja,
.simbolo__punto {
  transform-box: view-box;
  transform-origin: 12px 12px;
}

.simbolo__trazo {
  stroke-dasharray: 14;
}

/* En pantallas estrechas, el icono más pequeño: con 84 px y la letra al 200 %, el titular alemán no cabía a su lado. */
@media (max-width: 480px) {
  .simbolo {
    width: 64px;
    height: 55px;
  }

  .simbolo::before,
  .simbolo::after {
    width: 44px;
    height: 44px;
  }

  .simbolo svg {
    width: 27px;
    height: 27px;
  }
}

.simbolo--reloj { --i1: var(--azul); --i2: var(--lima); }
.simbolo--norte { --i1: var(--sol); --i2: var(--azul); }
.simbolo--sello { --i1: var(--lima); --i2: var(--bug); }
.simbolo--idiomas { --i1: var(--bug); --i2: var(--sol); }

/* Al entrar en pantalla: las lentes llegan desde el centro y el dibujo hace lo suyo (la aguja da una vuelta, la brújula busca
   el norte, el sello se firma, los puntos «escriben»). */
.js .con-icono .simbolo::before,
.js .con-icono .simbolo::after {
  translate: 0 0;
}

.js .con-icono:not(.visto) .simbolo::before { translate: 13px 7px; }
.js .con-icono:not(.visto) .simbolo::after { translate: -13px -7px; }

.js .con-icono .simbolo::before,
.js .con-icono .simbolo::after {
  transition: translate .9s cubic-bezier(.2, .8, .2, 1) .1s;
}

.con-icono.visto .simbolo--reloj .simbolo__aguja { animation: aguja 2.2s cubic-bezier(.45, 0, .2, 1) .2s both; }
.con-icono.visto .simbolo--norte .simbolo__aguja { animation: brujula 2.4s ease-out .2s both; }
.con-icono.visto .simbolo--sello .simbolo__trazo { animation: firma .9s ease-out .5s both; }
.con-icono.visto .simbolo--idiomas .simbolo__punto { animation: punto .9s ease-in-out .3s 2 both; }
.con-icono.visto .simbolo--idiomas .simbolo__punto:nth-of-type(2) { animation-delay: .45s; }
.con-icono.visto .simbolo--idiomas .simbolo__punto:nth-of-type(3) { animation-delay: .6s; }

@media (hover: hover) {
  .con-icono.visto:hover .simbolo--reloj .simbolo__aguja { animation-name: aguja-otra; animation-delay: 0s; }
  .con-icono.visto:hover .simbolo--norte .simbolo__aguja { animation-name: brujula-otra; animation-delay: 0s; }
  .con-icono.visto:hover .simbolo--sello .simbolo__trazo { animation-name: firma-otra; animation-delay: 0s; }
  .con-icono.visto:hover .simbolo--idiomas .simbolo__punto { animation-name: punto-otra; }
}

@keyframes aguja { from { rotate: -360deg; } to { rotate: 0deg; } }
@keyframes aguja-otra { from { rotate: -360deg; } to { rotate: 0deg; } }
@keyframes brujula { 0% { rotate: -50deg; } 35% { rotate: 28deg; } 60% { rotate: -14deg; } 80% { rotate: 6deg; } 100% { rotate: 0deg; } }
@keyframes brujula-otra { 0% { rotate: -50deg; } 35% { rotate: 28deg; } 60% { rotate: -14deg; } 80% { rotate: 6deg; } 100% { rotate: 0deg; } }
@keyframes firma { from { stroke-dashoffset: 14; } to { stroke-dashoffset: 0; } }
@keyframes firma-otra { from { stroke-dashoffset: 14; } to { stroke-dashoffset: 0; } }
@keyframes punto { 0%, 100% { translate: 0 0; } 40% { translate: 0 -2px; } }
@keyframes punto-otra { 0%, 100% { translate: 0 0; } 40% { translate: 0 -2px; } }

@media (prefers-reduced-motion: reduce) {
  .js .con-icono:not(.visto) .simbolo::before,
  .js .con-icono:not(.visto) .simbolo::after {
    translate: 0 0;
  }

  .con-icono .simbolo *,
  .con-icono .simbolo::before,
  .con-icono .simbolo::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------------------------------------------------------- la banda de luz (18-oct) */
/* [ole_escena clave="luz"] (parts/escena.php): una foto ancha de esquinas redondeadas, con el abanico del logo en pequeño
   pisando su esquina de abajo a la derecha. Las cuatro lentes tiñen la foto donde la cruzan y flotan despacio. */
.banda {
  position: relative;
  isolation: isolate;
  max-width: 1100px;
}

.banda__foto {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 7;
  object-fit: cover;
  object-position: 50% 52%;
  border-radius: clamp(20px, 3vw, 36px);
}

.banda__lente {
  position: absolute;
  bottom: -5%;
  left: 80%;                          /* girados, los pétalos de la derecha no pasan del borde de la página (a 320 px tampoco) */
  width: clamp(28px, 4.6%, 52px);
  margin-left: calc(clamp(28px, 4.6%, 52px) / -2);
  transform-origin: 50% 100%;
  rotate: var(--a);
  color: var(--l);
  mix-blend-mode: multiply;
}

/* Se mecen una vez al entrar en pantalla (ole.js le pone .visto a la banda), cada una un poco después de la anterior, y a los 4,75 s
   quedan quietas (WCAG 2.2.2). */
.banda.visto .banda__lente {
  animation: banda-flota 4s ease-in-out var(--retraso, 0s);
}

.banda__lente svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: currentColor;
}

.banda__lente--lima { --a: -39deg; --l: var(--lima); }
.banda__lente--azul { --a: -15deg; --l: var(--azul); --retraso: .25s; }
.banda__lente--sol { --a: 11deg; --l: var(--sol); --retraso: .5s; }
.banda__lente--bug { --a: 41deg; --l: var(--bug); --retraso: .75s; }

@keyframes banda-flota {
  0%, 100% { rotate: var(--a); }
  50% { rotate: calc(var(--a) * 1.15); }
}

@media (prefers-reduced-motion: reduce) {
  .banda.visto .banda__lente {
    animation: none;                  /* con el mismo selector que la animación: con .banda__lente solo, perdía (ole.js pone .visto igualmente) */
  }
}

/* ---------------------------------------------------------- enfoque de titulares */
/* Un titular con la clase enfoca empieza desenfocado y se aclara al entrar en pantalla (ole.js le pone .visto). */
.js .enfoca {
  filter: blur(9px);
  opacity: .15;
  transition: filter 1s cubic-bezier(.2, .7, .2, 1), opacity 1s ease;
}

.js .enfoca.visto {
  filter: none;
  opacity: 1;
}

/* ---------------------------------------------------------- las cuatro puertas */
.puertas {
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* una sola columna que encoge: con auto, la palabra más larga del titular la ensanchaba más allá de la pantalla */
  gap: 22px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Cuatro puertas desde el 18-oct (gafas graduadas): de dos en dos en tableta y en un portátil pequeño, y las cuatro en fila solo
   con el ancho entero de la página, donde cada tarjeta mide unos 265 px; ahí el titular baja un poco para que «Synundersökning» y
   «Kontaktlinsen» quepan enteros en vez de partirse. */
@media (min-width: 640px) {
  .puertas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1200px) {
  .puertas {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .puertas .puerta {
    padding-right: 26px;
    padding-left: 26px;
  }

  .puertas .puerta__titulo {
    font-size: 1.5rem;
  }
}

.puerta {
  --foco: var(--ink);
  /* Estado: en reposo la tarjeta es gris y el pétalo lleva el color; con el ratón encima o el foco, la lente de color
     crece desde el icono y llena la tarjeta, y el texto pasa a --on. */
  --lente: 0%;
  --tinta: var(--ink);
  --icono: var(--c);
  --mezcla: multiply;
  --flecha-fondo: var(--c);
  --flecha-tinta: var(--on);
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 15rem;
  margin: 0;
  padding: 30px 30px 26px;
  border-radius: var(--r);
  background: var(--cal2);
  color: var(--tinta);
  overflow-wrap: anywhere;            /* un titular con una palabra larga (en alemán o en danés) se parte en vez de ensanchar la tarjeta */
  transition: color .3s;
}

.puerta--examen { --c: var(--azul); --on: #fff; }
.puerta--gafas { --c: var(--bug); --on: #fff; }
.puerta--lentillas { --c: var(--lima); --on: var(--ink); }
.puerta--sol { --c: var(--sol); --on: var(--ink); }

/* Con el foco del teclado (:focus-visible), no con el de un clic: con :focus-within, la tarjeta en la que se hacía clic se
   quedaba llena de color al volver con «atrás» del navegador. El anillo no depende de :has(). */
.puerta:has(.puerta__enlace:focus-visible) {
  --lente: 150%;
  --tinta: var(--on);
  --icono: var(--on);
  --mezcla: normal;
  --flecha-fondo: var(--cal);
  --flecha-tinta: var(--ink);
}

@media (hover: hover) {
  .puerta:hover {
    --lente: 150%;
    --tinta: var(--on);
    --icono: var(--on);
    --mezcla: normal;
    --flecha-fondo: var(--cal);
    --flecha-tinta: var(--ink);
  }
}

/* La lente de color, detrás del contenido. */
.puerta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--c);
  clip-path: circle(var(--lente) at 58px 62px);
  transition: clip-path .55s cubic-bezier(.2, .7, .2, 1);
}

/* El icono es el pétalo del logo (ole_petalo_svg): la elipse, derecha y a todo el alto de su caja, que es la de siempre (44 x 63)
   y deja la elipse (21 px de ancho) en su centro, que es de donde crece la lente de color (clip-path de .puerta::before). */
.puerta .icono {
  display: block;
  width: 44px;
  height: 63px;
  margin: 0 0 22px 6px;
  fill: var(--icono);
  rotate: -14deg;
  mix-blend-mode: var(--mezcla);
  transition: fill .3s;
}

/* El gancho va abajo y puede partirse en varias líneas (en alemán, hasta tres en tarjetas estrechas): un radio fijo lo deja
   como una cápsula de una línea o un rectángulo redondeado de varias, y no como un óvalo. */
.puerta .gancho {
  margin: auto 0 0;
  padding: 6px 12px;
  border-radius: 18px;
  background: var(--cal);
  color: var(--ink);
  font-size: .78125rem;
  font-weight: 700;
  letter-spacing: .14em;
  line-height: 1.35;
  text-transform: uppercase;
}

.puerta__titulo {
  max-width: none;
  margin: 0 0 20px;
  font-size: clamp(1.5rem, 2.6vw, 1.875rem);
  letter-spacing: -.03em;
  line-height: 1.02;
  overflow-wrap: anywhere;           /* base.css pone break-word a los titulares, que no baja su tamaño mínimo: con anywhere la palabra larga se parte en la tarjeta */
}

/* Cada tarjeta es un solo enlace: el del título, estirado por toda la tarjeta. El anillo de foco lo dibuja ese
   pseudoelemento, fuera de la tarjeta (en tinta, que se ve sobre la página aunque la tarjeta esté llena de color). */
.puerta__enlace {
  color: inherit;
  text-decoration: none;
}

.puerta__enlace::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--r);
}

.puerta__enlace:focus-visible {
  outline: none;
}

.puerta__enlace:focus-visible::after {
  outline: 3px solid var(--foco);
  outline-offset: 3px;
}

/* La flecha, arriba a la derecha, a la altura del icono. */
.puerta__flecha {
  position: absolute;
  top: 40px;
  right: 30px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--flecha-fondo);
  color: var(--flecha-tinta);
  transition: background .3s, color .3s;
}

.puerta__flecha svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (min-width: 860px) {
  .puerta {
    min-height: 17.5rem;
  }
}

/* ---------------------------------------------------------- el azulejo del pie */
/* La banda de arriba del pie: cada bloque de 2 x 2 baldosas (.flor) forma la flor del logo con los cuatro colores y
   cada baldosa lleva un pétalo que nace en el centro del bloque. Caben tantas flores enteras como da el ancho de la
   pantalla (auto-fit: entre 80 y 112 px de flor); las que sobran caen a una fila de alto 0 y se recortan. Decorativo. */
.azulejo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(clamp(5rem, 8vw, 7rem), 1fr));
  grid-template-rows: auto;
  grid-auto-rows: 0;
  overflow: hidden;
  isolation: isolate;                 /* los pétalos se mezclan entre sí (multiply) cuando se juntan en el logo, no con el pie */
  background: var(--cal);
}

.flor {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.baldosa {
  /* La elipse del logo (rx 14, ry 41,13, derecha y con la base en (0, 0): la de ole_petalo_svg), con su base en la esquina de
     abajo a la derecha de la baldosa y la punta hacia su centro: translate(100 100) rotate(-45). Va a 1,2 de su tamaño: mide 98,7
     de largo por 33,6 de ancho (2.605 unidades de área de las 10.000 de la baldosa) y pasa del centro de la baldosa (a 71 unidades
     de la esquina) sin llegar a la de enfrente (a 141). Sus números repiten los de OLE_PETALO_RX y OLE_PETALO_RY
     (inc/logica/componentes.php): una prueba comprueba que son los del logo. */
  --petalo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cellipse cx='0' cy='-41.13' rx='14' ry='41.13' transform='translate(100 100) rotate(-45) scale(1.2)'/%3E%3C/svg%3E");
  position: relative;
  aspect-ratio: 1;
  box-shadow: inset 0 0 0 1px rgba(21, 23, 28, .08);   /* sin fondo propio: el pétalo que viene de la baldosa de al lado se ve encima */
}

.baldosa::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c);
  rotate: var(--g);
  -webkit-mask: var(--petalo) center / 100% 100% no-repeat;
  mask: var(--petalo) center / 100% 100% no-repeat;
  mix-blend-mode: multiply;
}

/* La posición dentro de la flor decide el color y el giro: arriba a la izquierda, lima; arriba a la derecha, azul;
   abajo a la izquierda, sol; abajo a la derecha, buganvilla. El giro lleva la base de cada pétalo al centro. */
.baldosa:nth-child(1) { --c: var(--lima); --g: 0deg; --tx: 8.9%; --ty: 41.56%; --d: 6.05deg; }
.baldosa:nth-child(2) { --c: var(--azul); --g: 90deg; --tx: 29.65%; --ty: 67.25%; --d: -59.93deg; }
.baldosa:nth-child(3) { --c: var(--sol); --g: 270deg; --tx: 70.97%; --ty: 61.78%; --d: 145.84deg; }
.baldosa:nth-child(4) { --c: var(--bug); --g: 180deg; --tx: 9.38%; --ty: 56.99%; --d: -94.17deg; }

/* La cenefa se mueve (18-oct), despacio y en bucle: cada flor se cierra en el logo y se vuelve a abrir. En 14 s: medio segundo de cenefa
   (empieza a moverse en cuanto se ve: con 4 s quieta al principio parecía que no se movía), 4,5 en que cada pétalo viaja y gira hasta su
   sitio en el abanico de la marca, 2 de logo, 4,5 de vuelta y 2,5 de cenefa. El logo cabe en la flor (123 x 97
   de sus 200 x 200 unidades) con el pétalo del mismo tamaño, así que solo se mueve y gira: --tx, --ty y --d (con rotate: var(--g)
   detrás) llevan la base del pétalo de la esquina de su baldosa, que es el centro de la flor, a la base de su elipse en el logo, y su
   ángulo, al del logo (OLE_PETALOS, inc/logica/componentes.php). Allí se cruzan y se mezclan (multiply), como en la marca.
   Las flores arrancan en ola, cada una un poco después que la de su izquierda. Solo se mueve con .azulejo--en-marcha, que ole.js pone
   mientras se ve y quita con el botón de pausa (WCAG 2.2.2); con «reducir movimiento», nunca. */
/* Solo se mueven las flores que se ven (.flor--viva, las de la primera fila: ole.js): las demás caen a una fila de alto 0 y no se ven.
   Arrancar las 96 animaciones a la vez daba fotogramas de más de 60 ms al llegar al pie con la CPU a la cuarta parte. */
.azulejo--vivo .flor--viva .baldosa::before {
  animation: cenefa-logo-1 14s ease-in-out var(--retraso-flor, 0s) infinite paused;
}

.azulejo--vivo .flor--viva .baldosa:nth-child(2)::before { animation-name: cenefa-logo-2; }
.azulejo--vivo .flor--viva .baldosa:nth-child(3)::before { animation-name: cenefa-logo-3; }
.azulejo--vivo .flor--viva .baldosa:nth-child(4)::before { animation-name: cenefa-logo-4; }

/* Con la misma especificidad que la regla de arriba, y detrás: con .azulejo--en-marcha .baldosa::before ganaba el «paused» de su
   abreviatura y la cenefa no se movía nunca. */
.azulejo--en-marcha .flor--viva .baldosa::before {
  animation-play-state: running;
}

.flor:nth-child(4n + 2) { --retraso-flor: .25s; }
.flor:nth-child(4n + 3) { --retraso-flor: .5s; }
.flor:nth-child(4n + 4) { --retraso-flor: .75s; }

/* Un @keyframes por baldosa, con sus números escritos (los de --tx, --ty y --d): con var() dentro de los fotogramas, Chrome no lleva la
   animación al compositor y recalculaba los 96 pétalos en cada fotograma (fotogramas de 60 a 70 ms con la CPU a la cuarta parte). */
@keyframes cenefa-logo-1 {
  0%, 4% { transform: translate(0, 0) rotate(0deg); }
  36%, 50% { transform: translate(8.9%, 41.56%) rotate(6.05deg); }
  82%, 100% { transform: translate(0, 0) rotate(0deg); }
}

@keyframes cenefa-logo-2 {
  0%, 4% { transform: translate(0, 0) rotate(0deg); }
  36%, 50% { transform: translate(29.65%, 67.25%) rotate(-59.93deg); }
  82%, 100% { transform: translate(0, 0) rotate(0deg); }
}

@keyframes cenefa-logo-3 {
  0%, 4% { transform: translate(0, 0) rotate(0deg); }
  36%, 50% { transform: translate(70.97%, 61.78%) rotate(145.84deg); }
  82%, 100% { transform: translate(0, 0) rotate(0deg); }
}

@keyframes cenefa-logo-4 {
  0%, 4% { transform: translate(0, 0) rotate(0deg); }
  36%, 50% { transform: translate(9.38%, 56.99%) rotate(-94.17deg); }
  82%, 100% { transform: translate(0, 0) rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .azulejo--vivo .flor--viva .baldosa::before {
    animation: none;
  }
}

/* El botón que para la cenefa: justo debajo de la banda, a la derecha, sin tapar ninguna flor (encima tapaba la primera). Va en el
   flujo y su margen de abajo, negativo, le devuelve el sitio que ocupa: cae en el aire de arriba del pie, que no baja. Fuera del azulejo,
   que no lleva nada enfocable. Lo enseña ole.js. */
.azulejo-pausa {
  --foco: var(--ink);
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: 8px 12px -44px auto;
  padding: 0;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  background: var(--cal);
  color: var(--ink);
  cursor: pointer;
}

.azulejo-pausa[hidden] {
  display: none;
}

.azulejo-pausa svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.azulejo-pausa__seguir,
.azulejo-pausa[aria-pressed="true"] .azulejo-pausa__pausa {
  display: none;
}

.azulejo-pausa[aria-pressed="true"] .azulejo-pausa__seguir {
  display: inline;
  fill: currentColor;
  stroke-width: 1.5;
}

/* ---------------------------------------------------------- carrusel de fotos (18-oct) */
/* parts/carrusel.php: una fila de fotos cuadradas que se desliza (scroll-snap) y, debajo, los puntos y los dos botones (carrusel.js).
   Dos lentes del color de la página pisan la esquina de abajo a la izquierda de la foto y la tiñen (multiply), como en los héroes. */
.carrusel {
  position: relative;
  width: min(100%, 560px);
}

.carrusel__marco {
  position: relative;
  isolation: isolate;
}

.carrusel__pista {
  display: flex;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  list-style: none;
  border-radius: var(--r);
  box-shadow: 0 38px 70px -40px rgba(21, 23, 28, .45);
}

.carrusel__pista::-webkit-scrollbar {
  display: none;
}

.carrusel__pista:focus-visible {
  outline: 3px solid var(--azul);
  outline-offset: 4px;
}

.carrusel__foto {
  flex: 0 0 100%;
  margin: 0;
  scroll-snap-align: start;
}

.carrusel__foto img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
}

.carrusel__lente {
  position: absolute;
  bottom: -5%;
  left: 3%;
  z-index: 1;
  width: 8.5%;
  transform-origin: 50% 100%;
  rotate: var(--a);
  color: var(--l);
  mix-blend-mode: multiply;
  pointer-events: none;
}

.carrusel__lente svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: currentColor;
}

.carrusel__lente--1 { --a: -16deg; --l: var(--pc, var(--azul)); }
.carrusel__lente--2 { --a: 18deg; --l: var(--pc2, var(--lima)); left: 7%; }

.carrusel__controles {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 20px;
}

.carrusel__controles[hidden] {
  display: none;
}

.carrusel__puntos {
  display: flex;
  gap: 7px;
}

.carrusel__punto {
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--ink) 22%, var(--cal));
  transition: width .3s, background-color .3s;
}

.carrusel__punto--actual {
  width: 24px;
  background: var(--ink);
}

.carrusel__botones {
  display: flex;
  gap: 10px;
}

.carrusel__boton {
  --foco: var(--ink);
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  background: var(--cal);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .2s, color .2s;
}

.carrusel__boton svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.carrusel__boton:hover:not(:disabled) {
  background: var(--ink);
  color: var(--cal);
}

.carrusel__boton:disabled {
  opacity: .35;
  cursor: default;
}

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

/* ---------------------------------------------------------- marcas */
.marcas__titulo {
  margin-bottom: 28px;
}

.marcas__lista {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px 52px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.marcas__marca {
  display: flex;
  align-items: center;
  margin: 0;
}

/* Los logos son wordmarks negros sobre fondo transparente de formas muy distintas (de 12:1 a 2:1): todos en una caja
   de 44 px de alto y, como mucho, 240 de ancho, con el dibujo entero dentro (contain). */
.marcas__logo {
  display: block;
  width: auto;
  max-width: min(240px, 70vw);
  height: 44px;
  object-fit: contain;
}

.marcas__nombre {
  color: var(--ink);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
}

/* ---------------------------------------------------------- reseñas de Google */
.resenas__titulo {
  margin-bottom: 28px;
}

.resenas__lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  gap: 22px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.resena {
  --foco: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0;
  padding: 26px 26px 22px;
  border-radius: var(--r);
  background: var(--cal2);
  /* Una palabra sin huecos (una URL, un nombre largo) se parte donde haga falta. Con anywhere, y no con break-word, cuenta
     también para el tamaño mínimo de la tarjeta: la columna de la rejilla encoge hasta la pantalla en vez de crecer hasta
     la palabra (una URL de 70 caracteres daba 815 px de scrollWidth a 390 px de pantalla). */
  overflow-wrap: anywhere;
}

/* Las estrellas: cinco máscaras de estrella en una pastilla Sol, rellenas hasta --n (1 a 5) con la tinta. El número
   también va dicho con palabras en el aria-label de la pastilla. */
.resena__nota {
  align-self: flex-start;
  margin: 0;
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--sol);
  line-height: 0;
}

.resena__nota i {
  display: block;
  width: 90px;
  height: 18px;
  background: linear-gradient(90deg, var(--ink) calc(var(--n) * 20%), rgba(21, 23, 28, .28) 0);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z'/%3E%3C/svg%3E") 0 0 / 20% 100% repeat-x;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z'/%3E%3C/svg%3E") 0 0 / 20% 100% repeat-x;
}

.resena__texto {
  margin: 0;
  color: var(--ink);
  font-size: 1.0625rem;
  line-height: 1.55;
}

.resena__texto p {
  margin: 0;
}

.resena__pie {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: auto 0 0;
  color: var(--ink2);
  font-size: .9375rem;
}

.resena__autor {
  color: var(--ink);
  font-weight: 700;
}

/* ---------------------------------------------------------- urgencias de turistas */
.urgencias {
  --foco: var(--ink);
  display: grid;
  grid-template-columns: minmax(0, 1fr);   /* como las puertas: una columna que encoge */
  gap: 28px 48px;
  align-items: center;
  padding: 34px 26px;
  border-radius: var(--r);
  background: var(--cal2);
  overflow-wrap: anywhere;
}

@media (min-width: 860px) {
  .urgencias {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    padding: 48px;
  }
}

/* El pétalo del logo (ole_petalo_svg), a todo el alto de su caja: la elipse mide 15 px de ancho en el centro de los 30 de la caja. */
.urgencias__icono {
  display: block;
  width: 30px;
  height: 43px;
  margin: 0 0 18px 4px;
  fill: var(--sol);
  rotate: -14deg;
  mix-blend-mode: multiply;
}

.urgencias__titulo {
  max-width: none;
  margin: 0 0 14px;
  font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  overflow-wrap: anywhere;
}

.urgencias__cuerpo {
  max-width: 34em;
  margin: 0;
  color: var(--ink2);
  font-size: 1.125rem;
}

.urgencias__acciones {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.urgencias__acciones .horario__estado {
  margin: 0 0 2px;
}

.urgencias__acciones .btn {
  width: 100%;
}

/* ---------------------------------------------------------- fotos provisionales ([ole_foto]) */
/* La fachada de la tienda y el retrato de Ole (parts/foto.php: una <figure> con un <img> WebP, en una o en varias versiones, ninguna más ancha que su
   foto de origen). El <img> lleva su width y su height, así que la página reserva el hueco con la proporción de la foto antes de que llegue (que es
   perezosa: no baja hasta que se acerca) y nada se mueve. Ocupa todo el ancho de su caja hasta un máximo (la fachada, 46 rem como las demos y el
   formulario; el retrato, 22 rem; si el fichero es más estrecho que la caja, el navegador lo agranda) y se redondea como las tarjetas. Sin rótulo: lo provisional lo marcan la carpeta, el data-provisional del <img> y una prueba que las enumera. Junto a su
   texto (el retrato en «Nosotros», la fachada en «Contacto») van dentro de una columna del editor y la llenan, hasta su máximo. */
.foto {
  margin: 0;
}

.foto img {
  width: 100%;
  border-radius: var(--r);
  background: var(--cal2);            /* el color del hueco mientras llega la foto */
}

.foto--fachada {
  max-width: 46rem;
}

.foto--ole {
  max-width: 22rem;
}

/* ---------------------------------------------------------- formulario de cita */
/* [ole_formulario_cita] (parts/formulario-cita.php; el envío lo hace assets/js/cita.js). Una tarjeta gris con los campos en dos
   columnas si la caja mide 36 rem o más (consulta de contenedor) y en una si no; etiquetas siempre visibles; los obligatorios llevan un asterisco (decorativo: la
   marca de verdad es el atributo required). Los bordes de los campos son --ink3 (3,4:1 sobre la tarjeta: vale para el borde de un
   control, no para texto); el texto, --ink o --ink2. Un campo con error lleva aria-invalid="true" (lo pone cita.js) y se ve con
   un borde rojo más grueso; el mensaje, en --m-lb (burdeos, 9:1). Foco: el anillo de base.css (azul, 3 px); en el botón, --ink. */
.form-cita {
  container-type: inline-size;        /* las columnas del formulario salen del ancho de su caja (ver el final del bloque) */
  width: 100%;
  max-width: 46rem;
  scroll-margin-top: 24px;            /* el enlace #cita deja algo de aire por encima de la tarjeta */
}

/* La tarjeta: el cuerpo (el formulario y el mensaje de «gracias») y, debajo, el respaldo con el teléfono. Sin JavaScript no se enseña
   el cuerpo (el formulario no podría enviarse) y la tarjeta es solo el respaldo; lo mismo si cita.js no llega a cargar, porque su
   etiqueta quita la clase js. El formulario y el mensaje de «gracias» comparten la celda de una rejilla: al enviar, la tarjeta
   conserva su alto y nada de lo que hay debajo se mueve. */
.form-cita__pila {
  padding: 26px 20px 28px;
  border-radius: var(--r);
  background: var(--cal2);
}

.form-cita__cuerpo {
  display: none;
  grid-template-columns: minmax(0, 1fr);
}

.js .form-cita__cuerpo {
  display: grid;
}

.form-cita__cuerpo > * {
  grid-area: 1 / 1;
  min-width: 0;
}

.form-cita--hecho .form-cita__form {
  visibility: hidden;
}

.form-cita__nota {
  margin: 0 0 20px;
  color: var(--ink2);
  font-size: .9375rem;
  line-height: 1.4;
}

.form-cita__rejilla {
  display: grid;
  gap: 20px 18px;
  margin-bottom: 22px;
}

.form-cita__campo {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.form-cita__campo > label,
.form-cita__campo > legend {
  display: block;
  width: 100%;
  margin: 0 0 8px;
  padding: 0;
  color: var(--ink);
  font-size: .9375rem;
  font-weight: 700;
  line-height: 1.3;
}

.form-cita__req {
  margin-left: .1em;
  color: var(--bug);
}

/* Los campos. 52 px de alto (zona táctil) y 17 px de letra: por debajo de 16 px, el iPhone amplía la página al tocarlos. */
.form-cita input[type="text"],
.form-cita input[type="tel"],
.form-cita input[type="email"],
.form-cita input[type="date"],
.form-cita select {
  display: block;
  width: 100%;
  min-height: 52px;
  margin: 0;
  padding: 0 16px;
  border: 1.5px solid var(--borde, var(--ink3));
  border-radius: 14px;
  background-color: var(--cal);
  color: var(--ink);
  font: 500 1.0625rem/1.3 var(--f);
}

.form-cita select {
  padding-right: 46px;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2315171c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 18px 18px;
  cursor: pointer;
  text-overflow: ellipsis;
}

/* El borde pasa a tinta con el ratón encima (solo con un puntero que pasa por encima: con el dedo, el hover se queda pegado), y a rojo
   con error: el error gana (va después y tiene más peso). */
@media (hover: hover) {
  .form-cita :where(input[type="text"], input[type="tel"], input[type="email"], input[type="date"], select):hover {
    --borde: var(--ink);
  }
}

.form-cita [aria-invalid="true"]:not(fieldset) {
  --borde: var(--m-sb);
  box-shadow: 0 0 0 1px var(--m-sb);
}

/* La franja: dos opciones como botones. El radio está encima, invisible, y recibe el clic y el teclado; el rótulo (span) es lo que se ve. */
.form-cita__opciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 7rem), 1fr));   /* dos columnas; una si 7 rem no caben dos veces (la letra al 200 % a 320 px) */
  gap: 10px;
}

.form-cita__opcion {
  position: relative;
  display: block;
  margin: 0;
}

.form-cita__opcion input {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.form-cita__opcion input:focus-visible {
  outline: none;
}

.form-cita__opcion span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 6px 14px;
  border: 1.5px solid var(--ink3);
  border-radius: 14px;
  background: var(--cal);
  color: var(--ink);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
  text-align: center;
  transition: background .2s, border-color .2s, color .2s;
}

@media (hover: hover) {
  .form-cita__opcion:hover span {
    border-color: var(--ink);
  }
}

.form-cita__opcion input:checked + span {
  border-color: var(--azul);
  background: var(--azul);
  color: #fff;
  font-weight: 700;
}

.form-cita__opcion input:focus-visible + span {
  outline: 3px solid var(--azul);
  outline-offset: 3px;
}

.form-cita__grupo[aria-invalid="true"] .form-cita__opcion span {
  border-color: var(--m-sb);
  box-shadow: 0 0 0 1px var(--m-sb);
}

/* La casilla de privacidad, con la frase al lado; la frase entera es el blanco del clic. */
.form-cita__privacidad {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;                          /* el hueco hasta el botón lo da la línea del aviso, que guarda su sitio */
}

.form-cita__privacidad input {
  flex: none;
  width: 24px;
  height: 24px;
  margin: 10px 0 0;
  accent-color: var(--azul);
  cursor: pointer;
}

.form-cita__privacidad label {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 0;
  color: var(--ink);
  font-size: .9375rem;
  line-height: 1.5;
  cursor: pointer;
}

.form-cita input[type="checkbox"][aria-invalid="true"] {
  outline: 3px solid var(--m-sb);
  outline-offset: 2px;
}

/* El cebo del antispam: fuera de la pantalla (no con display: none, que los robots detectan), del teclado y de los lectores de pantalla. */
.form-cita__web {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* El aviso (región aria-live) y el botón. El aviso guarda siempre el sitio de una línea, esté vacío o no: «Enviando…» sale al pulsar y se
   cambia por la respuesta (o desaparece, si es el «gracias») hasta 4,2 s después, y si la línea solo existiera mientras hay texto, la tarjeta
   y todo lo de debajo darían un salto de 37 px justo cuando llega la respuesta. */
.form-cita__estado {
  min-height: 1.45em;
  margin: 0 0 14px;
  color: var(--ink);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.45;
}

.form-cita__estado[data-tipo="error"] {
  color: var(--m-lb);
}

.form-cita__enviar {
  width: 100%;
  min-height: 56px;
  font-size: 1.0625rem;
}

.form-cita__enviar:disabled {
  opacity: .6;
  cursor: progress;
}

.form-cita__enviar:disabled:hover {
  background: var(--azul);
}

/* El mensaje de «gracias»: en el mismo sitio del formulario, centrado en la tarjeta. */
.form-cita__ok {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 20px;
  padding: 16px;
  border-radius: 16px;                /* el foco llega a este panel y su anillo sigue el borde: con esquinas vivas se vería cuadrado dentro de la tarjeta redonda */
  text-align: center;
}

.form-cita__ok[hidden] {
  display: none;
}

.form-cita__marca {
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: var(--lima);
  color: var(--ink);
}

.form-cita__marca svg {
  width: 32px;
  height: 32px;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.form-cita__ok-texto {
  max-width: 24em;
  margin: 0;
  color: var(--ink);
  font-size: clamp(1.25rem, 3.4vw, 1.625rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.25;
}

/* El respaldo: el teléfono y el WhatsApp. Sin JavaScript es lo único que enseña la tarjeta (con su explicación); con JavaScript solo
   se ve cuando cita.js lo pide, debajo del formulario (un límite de envíos o un fallo de red: .form-cita--ayuda). */
.js .form-cita__alternativa {
  display: none;
}

.js .form-cita--ayuda .form-cita__alternativa {
  display: block;
  margin-top: 22px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

.form-cita__sin-js {
  margin: 0 0 14px;
  color: var(--ink);
  font-weight: 600;
}

.js .form-cita__sin-js {
  display: none;
}

.form-cita__botones {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Con sitio (desde 36 rem de caja), los campos en dos columnas y el botón a su ancho. Es una consulta de contenedor y no de pantalla:
   la misma pieza vale a ancho completo o en una columna de la página de contacto, y en una caja estrecha se queda en una columna. */
@container (min-width: 36rem) {
  .form-cita__pila {
    padding: 40px;
  }

  .form-cita__rejilla {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .form-cita__campo--ancho {
    grid-column: 1 / -1;
  }

  .form-cita__enviar {
    width: auto;
    min-width: 16rem;
  }
}

/* ---------------------------------------------------------- movimiento reducido */
/* Con «reducir movimiento», todo quieto (base.css ya deja las duraciones a casi 0; aquí se quita lo que es solo
   movimiento): los pétalos sin animar ni inclinar, y los titulares nítidos desde el principio. Las puertas siguen
   cambiando de color con el ratón o el foco, sin transición. */
@media (prefers-reduced-motion: reduce) {
  .petalo,
  .petalo svg {
    animation: none;
  }

  .abanico {
    transition: none;
  }

  .js .enfoca {
    filter: none;
    opacity: 1;
    transition: none;
  }

  .puerta,
  .puerta::before,
  .puerta .icono,
  .puerta__flecha {
    transition: none;
  }
}

/* ---------------------------------------------------------- alto contraste de Windows (forced-colors) */
/* Con el alto contraste, el navegador pone los colores del sistema en todo y quita fondos, sombras y degradados: lo que solo se distinguía
   por ellos se queda igual que lo que tiene al lado. Aquí se le da forma con bordes y, donde hay que marcar algo, con los colores del
   sistema. Lo vigila test_alto_contraste.py (Playwright emula forced-colors: active). Los botones del aviso de cookies ya llevan su borde
   transparente (carcasa.css), que el alto contraste dibuja. */
@media (forced-colors: active) {
  /* .btn no lleva borde y su fondo se va: quedaba un texto suelto. .btn--claro dibuja su contorno con una sombra interior, que tampoco se ve. */
  .btn {
    border: 2px solid ButtonText;
  }

  /* Los botones de la carcasa se pintan también solo con fondo, como .btn: «Pedir cita» de la cabecera y los de la barra fija del móvil. */
  .cabecera__cta,
  .barra-movil a {
    border: 2px solid ButtonText;
  }

  /* La opción marcada de la franja era azul con la letra blanca y, sin el fondo, igual que la otra. Con forced-color-adjust: none se
     usan los colores de la selección del sistema; si no, el navegador pinta una placa detrás de la letra y, si las dos son del mismo
     color, no se lee. */
  .form-cita__opcion input:checked + span {
    forced-color-adjust: none;
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
  }

  /* Un campo con error perdía su borde rojo y su sombra: ahora lleva un borde doble, más grueso (la casilla de privacidad, su contorno). */
  .form-cita [aria-invalid="true"]:not(fieldset),
  .form-cita__grupo[aria-invalid="true"] .form-cita__opcion span {
    border-style: double;
    border-width: 4px;
  }

  /* El círculo de «gracias» es un fondo: sin él, la marca quedaba suelta. */
  .form-cita__marca {
    border: 3px solid CanvasText;
  }
}

/* ---------------------------------------------------------- la cita es una solicitud (18-oct) */
/* La nota de arriba del formulario: lo que hay que saber antes de pedir (que la óptica confirma, de lunes a viernes, desde el segundo
   día laborable), con las dos lentes de las viñetas delante. Y la ayuda del día, debajo de su campo (cita.js le pone la primera fecha). */
.form-cita__solicitud {
  position: relative;
  margin: 0 0 14px;
  padding: 14px 16px 14px 48px;
  border-radius: 14px;
  background: #e8f1f7;
  color: var(--ink);
  font-size: .9375rem;
  line-height: 1.5;
}

.form-cita__solicitud::before {
  content: "";
  position: absolute;
  top: 18px;
  left: 16px;
  width: 22px;
  height: 13px;
  background:
    radial-gradient(circle at 6.5px 50%, var(--azul) 0 6.3px, transparent 6.6px),
    radial-gradient(circle at calc(100% - 6.5px) 50%, var(--lima) 0 6.3px, transparent 6.6px);
  background-blend-mode: multiply;
}

.form-cita__ayuda {
  margin: 6px 0 0;
  color: var(--ink2);
  font-size: .875rem;
  line-height: 1.45;
}

/* La ventana que sale al enviar (#cita-aviso): la repite, con el teléfono como lo más sencillo, rápido y fiable. */
.cita-aviso {
  --foco: var(--ink);
  width: min(30rem, calc(100vw - 32px));
  padding: 30px 28px 28px;
  border: 0;
  border-radius: 24px;
  background: var(--cal);
  color: var(--ink);
  box-shadow: 0 30px 80px -20px rgba(21, 23, 28, .5);
  text-align: center;
}

.cita-aviso::backdrop,
.cita-modal::backdrop {
  background: rgba(21, 23, 28, .5);
}

.cita-aviso__marca {
  display: inline-flex;
  margin-bottom: 10px;
  isolation: isolate;
}

.cita-aviso__marca svg {
  width: 20px;
  height: auto;
  mix-blend-mode: multiply;
}

.cita-aviso__marca svg:first-child { fill: var(--azul); rotate: -16deg; }
.cita-aviso__marca svg + svg { margin-left: -9px; fill: var(--lima); rotate: 16deg; }

.cita-aviso__titulo {
  margin: 0 0 10px;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
}

.cita-aviso__texto {
  margin: 0 0 10px;
}

.cita-aviso__botones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}

/* La ventana del formulario (botón flotante): la cabecera se queda arriba mientras se baja por el formulario. */
.cita-modal {
  --foco: var(--ink);
  width: min(46rem, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 0;
  border-radius: 26px;
  background: var(--cal);
  color: var(--ink);
  box-shadow: 0 30px 80px -20px rgba(21, 23, 28, .5);
}

.cita-modal__cabecera {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px 16px 26px;
  border-bottom: 1px solid var(--line);
  background: var(--cal);
}

.cita-modal__titulo {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -.02em;
}

.cita-modal__cerrar {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  background: var(--cal);
  color: var(--ink);
  cursor: pointer;
}

.cita-modal__cerrar svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}

.cita-modal__cuerpo {
  padding: 22px 26px 26px;
}

.cita-modal__cuerpo .form-cita {
  max-width: none;
  margin: 0;
}

/* Dentro de la ventana, el formulario sin su tarjeta gris: la ventana ya es la tarjeta. */
.cita-modal__cuerpo .form-cita__pila {
  padding: 0;
  border-radius: 0;
  background: none;
}

.cita-modal__estado,
.cita-modal__error {
  margin: 0;
  color: var(--ink2);
}

.cita-modal__error .btn {
  margin-top: 14px;
}

.cita-modal__estado[hidden],
.cita-modal__error[hidden] {
  display: none;
}

/* ---------------------------------------------------------- botón flotante de contacto (18-oct) */
/* Abajo a la derecha, desde 800 px (en el móvil ya está la barra de abajo). Es la marca del logo: al pasar el ratón sus pétalos se abren
   un poco más, como el abanico, y al abrirlo, del todo. El menú sube encima, con una lente de un color del logo en cada salida. */
.contacto-flotante {
  display: none;
}

@media (min-width: 800px) {
  .contacto-flotante:not([hidden]) {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 45;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 12px;
    pointer-events: none;            /* la caja abarca el menú aunque esté cerrado: sin esto se comía los clics de lo que hay debajo */
  }
}

.contacto-flotante__boton,
.contacto-flotante--abierto .contacto-flotante__menu {
  pointer-events: auto;
}

.contacto-flotante__boton {
  --foco: var(--ink);
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--cal);
  box-shadow: 0 0 0 1px var(--line), 0 16px 34px -12px rgba(21, 23, 28, .45);
  cursor: pointer;
  transition: box-shadow .3s, scale .3s;
}

.contacto-flotante__boton:hover {
  box-shadow: 0 0 0 1px var(--line), 0 20px 40px -12px rgba(21, 23, 28, .55);
  scale: 1.05;
}

.contacto-flotante__marca {
  width: 40px;
  height: auto;
  overflow: visible;
  isolation: isolate;
}

.contacto-flotante__marca ellipse {
  mix-blend-mode: multiply;
}

.marca__petalo {
  transform-box: view-box;
  transition: rotate .45s cubic-bezier(.2, .8, .2, 1);
}

.contacto-flotante__boton:hover .marca__petalo { rotate: calc(var(--a) * .18); }
.contacto-flotante--abierto .marca__petalo { rotate: calc(var(--a) * .6); }

.contacto-flotante__menu {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  visibility: hidden;
}

.contacto-flotante--abierto .contacto-flotante__menu {
  visibility: visible;
}

.contacto-flotante__menu li {
  opacity: 0;
  translate: 0 10px;
  transition: opacity .25s, translate .3s cubic-bezier(.2, .8, .2, 1);
}

.contacto-flotante--abierto .contacto-flotante__menu li {
  opacity: 1;
  translate: 0 0;
}

.contacto-flotante--abierto .contacto-flotante__menu li:nth-last-child(2) { transition-delay: .04s; }
.contacto-flotante--abierto .contacto-flotante__menu li:nth-last-child(3) { transition-delay: .08s; }

.contacto-flotante__opcion {
  --foco: var(--ink);
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 8px 22px 8px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--cal);
  box-shadow: 0 0 0 1px var(--line), 0 12px 28px -14px rgba(21, 23, 28, .45);
  color: var(--ink);
  font: 700 1rem/1.2 var(--f);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.contacto-flotante__opcion:hover {
  box-shadow: 0 0 0 1.5px var(--ink), 0 12px 28px -14px rgba(21, 23, 28, .45);
}

.contacto-flotante__texto small {
  display: block;
  margin-top: 2px;
  color: var(--ink2);
  font-size: .8125rem;
  font-weight: 500;
}

/* La lente de cada salida: dos círculos de colores del logo que se cruzan (multiply), como las viñetas. */
.contacto-flotante__lente {
  flex: none;
  width: 34px;
  height: 22px;
  background:
    radial-gradient(circle at 11px 50%, var(--l1) 0 10.6px, transparent 11px),
    radial-gradient(circle at calc(100% - 11px) 50%, var(--l2) 0 10.6px, transparent 11px);
  background-blend-mode: multiply;
}

.contacto-flotante__opcion--llamar { --l1: var(--azul); --l2: var(--lima); }
.contacto-flotante__opcion--cita { --l1: var(--lima); --l2: var(--sol); }
.contacto-flotante__opcion--correo { --l1: var(--sol); --l2: var(--bug); }

@media (prefers-reduced-motion: reduce) {
  .contacto-flotante__boton,
  .marca__petalo,
  .contacto-flotante__menu li {
    transition: none;
  }
}
