@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap");

/* ── Motion primitives (no hay familia motion en tokens: viven aquí) ── */
:root {
  --up-ease-out: cubic-bezier(.22, 1, .36, 1);
  --up-ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --up-dur-fast: 180ms;
  --up-dur-base: 320ms;
  --up-dur-slow: 720ms;
  --up-reveal-distance: 28px;
  --up-stagger: 80ms;
}

*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; background: var(--surface); color: var(--ink); font-family: var(--font-sans); -webkit-font-smoothing: antialiased; }
/* Scrollbar del sitio con los tokens de marca en vez del scrollbar gris del sistema
   operativo (agregado local, no está en el bundle original). Firefox usa
   scrollbar-width/scrollbar-color; Chrome/Safari/Edge, los pseudo-elementos
   ::-webkit-scrollbar. Se aplica global (html) y también a .up-specialties, el único
   contenedor con su propio scroll horizontal del tema. */
html { scrollbar-width: thin; scrollbar-color: var(--brand) var(--surface-sky); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--surface-sky); }
::-webkit-scrollbar-thumb { background: var(--brand); border-radius: var(--radius-pill); border: 2px solid var(--surface-sky); }
::-webkit-scrollbar-thumb:hover { background: var(--brand-strong); }
.up-container { width: min(1200px, 100% - 2 * var(--space-6)); margin-inline: auto; }
.up-em, .up-display em, .up-h1 em, .up-h2 em { font-style: normal; font-weight: 600; color: var(--brand-strong); }
.up-display { margin: 0; font-size: clamp(40px, 6vw, 64px); line-height: 1.06; font-weight: 300; letter-spacing: -0.03em; text-wrap: balance; }
.up-h2 { margin: 0; font-size: clamp(28px, 3.6vw, 36px); line-height: 1.17; font-weight: 400; letter-spacing: -0.02em; text-wrap: balance; }
.up-lead { margin: 0; font-size: 19px; line-height: 31px; color: var(--ink-muted); max-width: 56ch; }
.up-eyebrow { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; font-size: 12px; line-height: 16px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-muted); }
.up-eyebrow--glass { padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill); background: var(--surface-glass); border: 1px solid var(--border); backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%); }
.up-eyebrow__dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--accent-coral); box-shadow: 10px 0 0 var(--puzzle-blue), 20px 0 0 var(--puzzle-yellow); margin-right: 22px; }

/* Pastel mesh background (eco del degradado difuso de la pieza) */
.up-mesh { background:
  radial-gradient(55% 60% at 0% 0%, var(--surface-sky) 0%, transparent 70%),
  radial-gradient(45% 55% at 100% 0%, var(--surface-blush) 0%, transparent 70%),
  radial-gradient(55% 60% at 75% 100%, var(--surface-lilac) 0%, transparent 70%),
  radial-gradient(40% 40% at 10% 100%, var(--surface-peach) 0%, transparent 70%),
  var(--surface); }

/* Decorative motifs */
.up-plus { position: absolute; width: 28px; height: 28px; color: var(--surface-raised); pointer-events: none; }
.up-plus::before, .up-plus::after { content: ""; position: absolute; left: 50%; top: 50%; background: currentColor; border-radius: 2px; }
.up-plus::before { width: 100%; height: 3px; transform: translate(-50%, -50%); }
.up-plus::after { width: 3px; height: 100%; transform: translate(-50%, -50%); }
.up-plus--ink { color: var(--brand); opacity: .55; }
.up-blob { position: absolute; border-radius: var(--radius-pill); pointer-events: none; }
.up-float { animation: up-float 7s var(--up-ease-in-out) infinite alternate; }
@keyframes up-float { from { transform: translate3d(0, -6px, 0); } to { transform: translate3d(0, 8px, 0); } }

/* ── Reveal on scroll (reemplazo liviano de AOS; se activa sólo si html.up-motion) ── */
.up-motion [data-up-reveal] { opacity: 0; transform: translate3d(0, var(--up-reveal-distance), 0); transition: opacity var(--up-dur-slow) var(--up-ease-out), transform var(--up-dur-slow) var(--up-ease-out); transition-delay: var(--up-delay, 0ms); will-change: opacity, transform; }
.up-motion [data-up-reveal="fade"] { transform: none; }
.up-motion [data-up-reveal="zoom"] { transform: scale(.94); }
.up-motion [data-up-reveal="left"] { transform: translate3d(calc(-1 * var(--up-reveal-distance)), 0, 0); }
.up-motion [data-up-reveal="right"] { transform: translate3d(var(--up-reveal-distance), 0, 0); }
/* 85% y no 100%: si el clip-path llega a 100% el elemento queda con área visible
   real 0 -- en Chromium eso hace que IntersectionObserver calcule el ratio de
   intersección como ~0 sin importar la posición de scroll real, así que nunca
   cruza el threshold y nunca se le agrega .is-in (candado: nunca se revela).
   El opacity:0 de la regla de base ya lo esconde del todo, así que el 15% que
   queda visible geométricamente no se nota -- pero le alcanza a IO para medir
   bien cuándo entra en pantalla. */
.up-motion [data-up-reveal="mask"] { transform: none; clip-path: inset(0 0 85% 0 round var(--radius-xl)); transition-property: opacity, clip-path; }
.up-motion [data-up-reveal].is-in { opacity: 1; transform: none; }
.up-motion [data-up-reveal="mask"].is-in { clip-path: inset(0 0 0 0 round var(--radius-xl)); }
[data-up-parallax] { will-change: transform; }

/* ── Button ── */
.up-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: 40px; padding: 10px 20px; border-radius: var(--radius-md); border: 1.5px solid transparent; font-family: var(--font-sans); font-size: 13px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; line-height: 18px; text-decoration: none; cursor: pointer; white-space: nowrap; transition: transform var(--up-dur-fast) var(--up-ease-out), box-shadow var(--up-dur-base) var(--up-ease-out), background-color var(--up-dur-base) var(--up-ease-out), color var(--up-dur-base); }
.up-btn:hover { transform: translateY(-2px); }
.up-btn:active { transform: translateY(0) scale(.98); }
.up-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.up-btn svg { width: 16px; height: 16px; flex: none; }
.up-btn__arrow { transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-btn:hover .up-btn__arrow { transform: translateX(4px); }
.up-btn--primary { background: var(--brand-strong); color: var(--on-brand); }
.up-btn--primary:hover { box-shadow: var(--shadow-card); }
.up-btn--secondary { background: var(--surface-glass); color: var(--brand-strong); border-color: var(--brand-strong); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.up-btn--secondary:hover { background: var(--surface-lilac); }
.up-btn--ghost { background: transparent; color: var(--ink); padding-inline: var(--space-3); }
.up-btn--ghost:hover { background: var(--surface-lilac); }
.up-btn--round { width: 40px; padding: 0; border-radius: var(--radius-pill); }
.up-btn--lg { min-height: 46px; padding-inline: var(--space-6); }

/* ── Header (glass, sticky, se compacta con scroll) ── */
.up-header { position: sticky; top: 0; z-index: var(--z-header); transition: padding var(--up-dur-base) var(--up-ease-out); padding: var(--space-4) 0; }
.up-header__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-6); padding: var(--space-3) var(--space-8); border-radius: var(--radius-pill); background: var(--surface-glass); border: 1px solid var(--border); backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%); transition: box-shadow var(--up-dur-base) var(--up-ease-out), background-color var(--up-dur-base); }
.up-header.is-scrolled { padding: var(--space-2) 0; }
.up-header.is-scrolled .up-header__bar { box-shadow: var(--shadow-float); }
/* Ajuste de tamaño pedido por el cliente (más grande que el bundle original de
   36px/32px, pero un 20% más chico que la primera prueba de 96px/84px, que se
   sentía apretada contra el borde de la cápsula). Padding vertical del bar subido
   de --space-2 a --space-3 para que el logo respire. En mobile el header no tiene
   lugar para un logo grande al lado del botón "Agendá tu cita" y el toggle del
   drawer, así que ahí queda un poco más chico (pero igual más grande que el
   original) para no volver a romper 360/768px. */
.up-header__logo img { height: 77px; width: auto; display: block; transition: height var(--up-dur-base) var(--up-ease-out); }
.up-header.is-scrolled .up-header__logo img { height: 67px; }
/* El botón "Agendá tu cita" del bar se saca en mobile (pedido del cliente): abajo de
   1024px el bar queda solo logo + toggle, así que hay mucho más lugar para el logo y
   para separarlo del borde de la cápsula. El botón de reserva sigue disponible arriba
   del todo en el drawer (.up-header__drawer-book), no se pierde la acción. El umbral
   del menú se subió de 880 a 1024px (ver .up-header__nav más abajo): con el padding
   en X más generoso, "Inicio Especialidades Equipo Quienes Somos Contacto" + logo +
   acciones ya no entraban en una sola línea entre 881-1000px más o menos. */
@media (max-width: 1024px) {
  .up-header__book { display: none; }
  .up-header__logo img { height: 60px; }
  .up-header.is-scrolled .up-header__logo img { height: 52px; }
  .up-header__bar { gap: var(--space-4); padding: var(--space-3) var(--space-6); }
}
@media (max-width: 400px) {
  .up-header__logo img { height: 48px; }
  .up-header.is-scrolled .up-header__logo img { height: 42px; }
  .up-header__bar { padding: var(--space-2) var(--space-4); }
}
/* Bug visual real: el bundle original invertía logo.svg por CSS para el footer oscuro,
   pero nuestro isotipo tiene un círculo blanco + piezas de color detrás del wordmark —
   invert(1) lo vuelve un círculo negro y corre los colores de marca a sus opuestos.
   El tema ya trae logo-white.svg (variante blanca real, ver assets/images/), así que
   el footer usa ese archivo directamente y acá no hace falta ningún filtro. */
.up-header__nav { display: flex; gap: var(--space-6); }
.up-header__nav a { position: relative; color: var(--ink); text-decoration: none; font-size: 14px; font-weight: 500; padding: var(--space-2) 0; white-space: nowrap; }
.up-header__nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 2px; height: 1.5px; background: var(--brand-strong); transform: scaleX(0); transform-origin: left; transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-header__nav a:hover::after, .up-header__nav a[aria-current="page"]::after { transform: scaleX(1); }
.up-header__nav a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; border-radius: 4px; }
.up-header__actions { display: flex; align-items: center; gap: var(--space-2); }
@media (max-width: 1024px) { .up-header__nav { display: none; } }

/* ── Hero ── */
.up-hero { position: relative; overflow: hidden; padding: var(--space-12) 0 var(--space-20); }
.up-hero__grid { position: relative; z-index: 2; display: grid; grid-template-columns: 1.05fr 1fr; gap: var(--space-12); align-items: center; }
.up-hero__copy { display: grid; gap: var(--space-6); justify-items: start; }
.up-hero__ctas { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.up-hero__social { display: flex; align-items: center; gap: var(--space-4); font-size: 14px; color: var(--ink-muted); }
.up-hero__social a { display: inline-flex; align-items: center; gap: 6px; color: var(--ink); font-weight: 500; text-decoration: none; border-bottom: 1px solid var(--border); padding-bottom: 2px; transition: border-color var(--up-dur-fast); }
.up-hero__social a:hover { border-color: var(--brand-strong); }
.up-hero__social a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; border-radius: 2px; }
.up-hero__social svg { width: 16px; height: 16px; color: var(--brand-strong); }
.up-hero__media { position: relative; aspect-ratio: 4 / 4.4; }
.up-hero__photo { position: absolute; inset: 6% 4% 0 10%; border-radius: var(--radius-xl); overflow: hidden; background: linear-gradient(160deg, var(--surface-sky), var(--surface-lilac) 55%, var(--surface-blush)); border: 1px solid var(--border); }
.up-hero__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.up-hero__placeholder { position: absolute; inset: 0; display: grid; place-content: center; gap: var(--space-2); text-align: center; color: var(--ink-muted); font-size: 13px; }
.up-hero__arc { width: 64%; aspect-ratio: 1; right: -14%; top: -6%; background: var(--brand); opacity: .88; }
.up-hero__disc { aspect-ratio: 1; }
.up-hero__disc--yellow { width: 20%; left: 0; bottom: 12%; background: var(--puzzle-yellow); }
.up-hero__disc--coral { width: 9%; left: 4%; top: 4%; background: var(--puzzle-coral); }
.up-hero__disc--blue { width: 7%; right: 34%; bottom: -1%; background: var(--puzzle-blue); }
@media (max-width: 880px) { .up-hero__grid { grid-template-columns: 1fr; } .up-hero__media { max-width: 480px; } }

/* ── Specialty card ── */
.up-specialties { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); align-items: stretch; gap: var(--space-6); perspective: 1200px; }
/* Bug real: overflow-x:auto sin overflow-y explícito promueve el eje Y a "auto"
   también (así lo pide el spec de CSS cuando un eje no es "visible" y el otro sí),
   así que el carrusel mostraba una scrollbar vertical de más apenas una tarjeta
   quedaba unos px más alta que las demás. align-items:stretch además pareja la
   altura de todas las tarjetas de la fila (ya es el default de grid, se deja
   explícito para que no dependa de eso). */
@media (max-width: 640px) { .up-specialties { grid-auto-flow: column; grid-auto-columns: 78%; grid-template-columns: none; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; padding-bottom: var(--space-4); } .up-specialties > * { scroll-snap-align: start; } }
/* Tilt 3D con el mouse (motion.js > data-up-tilt, agregado local): --tilt-x/--tilt-y
   los mueve motion.js siguiendo el puntero y quedan en 0deg en reposo/touch/reduced-
   motion, así que esta regla no cambia nada quien no tenga JS o prefiera menos movimiento. */
.up-card { position: relative; display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-8) var(--space-6) var(--space-6); background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); color: var(--ink); text-decoration: none; overflow: hidden; transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); transition: transform var(--up-dur-base) var(--up-ease-out), box-shadow var(--up-dur-base) var(--up-ease-out), border-color var(--up-dur-base); }
.up-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 55%; background: linear-gradient(180deg, var(--up-tint, var(--surface-lilac)), transparent); opacity: .7; transition: opacity var(--up-dur-base); pointer-events: none; }
.up-card:hover { transform: translateY(-6px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); box-shadow: var(--shadow-card); border-color: transparent; }
/* Bug real (preexistente, no de esta sesión): ".up-motion [data-up-reveal].is-in {
   transform:none}" tiene más especificidad que ".up-card:hover" y ".up-card", así que
   una vez que la tarjeta ya se reveló (que es casi siempre, apenas entra en pantalla)
   el "transform:none" del sistema de reveal ganaba y el hover-lift original NUNCA se
   veía, con o sin tilt. Se sube la especificidad acá para que gane la de la tarjeta. */
.up-motion .up-card[data-up-reveal].is-in { transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); }
.up-motion .up-card[data-up-reveal].is-in:hover { transform: translateY(-6px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); }
.up-card:hover::before { opacity: 1; }
.up-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.up-card > * { position: relative; }
.up-card--sky { --up-tint: var(--surface-sky); } .up-card--blush { --up-tint: var(--surface-blush); } .up-card--peach { --up-tint: var(--surface-peach); } .up-card--lilac { --up-tint: var(--surface-lilac); }
.up-card__icon { width: 56px; height: 56px; border-radius: var(--radius-md); background: var(--surface-raised); color: var(--brand-strong); display: grid; place-items: center; box-shadow: 0 6px 16px -6px rgba(107,74,138,.25); transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-card:hover .up-card__icon { transform: rotate(-6deg) scale(1.06); }
.up-card__icon svg { width: 26px; height: 26px; }
.up-card__title { margin: 0; font-size: 20px; line-height: 28px; font-weight: 600; letter-spacing: -0.01em; }
.up-card__text { margin: 0; font-size: 15px; line-height: 25px; color: var(--ink-muted); flex: 1; }
.up-card__foot { display: flex; align-items: center; justify-content: space-between; padding-top: var(--space-4); border-top: 1px solid var(--border); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-strong); }
.up-card__go { width: 36px; height: 36px; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--surface-lilac); transition: transform var(--up-dur-base) var(--up-ease-out), background-color var(--up-dur-base), color var(--up-dur-base); }
.up-card__go svg { width: 16px; height: 16px; }
.up-card:hover .up-card__go { background: var(--brand-strong); color: var(--on-brand); transform: translateX(4px); }

/* ── Badge ── */
.up-badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: 4px var(--space-3); border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; line-height: 16px; background: var(--surface-lilac); color: var(--brand-strong); }
.up-badge--new { background: var(--accent-coral); color: #1c1a22; }

/* ── Booking (entrada a LatePoint + tema del widget) ── */
.up-booking { position: relative; overflow: hidden; display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-12); align-items: center; padding: var(--space-12); border-radius: var(--radius-xl); background: var(--surface-peach); }
.up-booking__copy { position: relative; display: grid; gap: var(--space-6); justify-items: start; }
/* custom.css (legacy) trae una regla global "ol li::before" con su propio círculo
   numerado (rosa, 19px) para un <ol> genérico de una página vieja — acá pisaba el
   badge propio de .up-steps__n (40px, con su color por paso). .up-steps es el único
   <ol> del tema hoy, así que se neutraliza puntual acá en vez de tocar la regla
   legacy (podría seguir haciendo falta en alguna página Bootstrap sin rediseñar). */
.up-steps, .up-steps li { padding-left: 0; margin: 0; }
.up-steps li::before { content: none; }
.up-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); counter-reset: step; position: relative; }
.up-steps::before { content: ""; position: absolute; left: 19px; top: 20px; bottom: 20px; width: 1.5px; background: var(--brand); opacity: .4; transform-origin: top; transition: transform 1.2s var(--up-ease-out); }
.up-motion .up-steps:not(.is-in)::before { transform: scaleY(0); }
.up-steps li { display: grid; grid-template-columns: 40px 1fr; gap: var(--space-4); align-items: start; }
.up-steps__n { width: 40px; height: 40px; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--puzzle-blue); color: var(--ink); font-weight: 600; font-size: 15px; position: relative; }
.up-steps li:nth-child(2) .up-steps__n { background: var(--puzzle-yellow); }
.up-steps li:nth-child(3) .up-steps__n { background: var(--puzzle-coral); }
.up-steps__t { margin: 0; font-weight: 600; font-size: 16px; line-height: 24px; }
.up-steps__d { margin: 0; font-size: 14px; line-height: 21px; color: var(--ink-muted); }
.up-booking__alt { font-size: 14px; color: var(--ink-muted); }
.up-booking__alt a { color: var(--brand-strong); font-weight: 600; }

/* Widget LatePoint tematizado (objetivo visual del override CSS) */
.up-lp { position: relative; display: grid; gap: var(--space-4); padding: var(--space-6); border-radius: var(--radius-lg); background: var(--surface-raised); box-shadow: var(--shadow-float); }
.up-lp__head { display: flex; justify-content: space-between; align-items: center; font-size: 12px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); }
.up-lp__progress { display: flex; gap: 6px; } .up-lp__progress i { width: 22px; height: 4px; border-radius: 4px; background: var(--border); } .up-lp__progress i.on { background: var(--brand-strong); }
.up-lp__opt { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); border: 1.5px solid var(--border); font-size: 15px; font-weight: 500; transition: border-color var(--up-dur-fast), background-color var(--up-dur-fast); cursor: pointer; }
.up-lp__opt:hover { border-color: var(--border-control); }
.up-lp__opt[aria-checked="true"] { border-color: var(--brand-strong); background: var(--surface-lilac); }
.up-lp__slots { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2); }
.up-lp__slot { padding: var(--space-2) 0; text-align: center; border-radius: var(--radius-sm); border: 1.5px solid var(--border); font-size: 14px; font-weight: 500; font-variant-numeric: tabular-nums; }
.up-lp__slot[aria-checked="true"] { background: var(--brand-strong); border-color: var(--brand-strong); color: var(--on-brand); }
@media (max-width: 880px) { .up-booking { grid-template-columns: 1fr; padding: var(--space-8) var(--space-6); } }

/* ── Social feed ── */
.up-social { display: grid; gap: var(--space-8); }
.up-social__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: var(--space-6); }
.up-social__handle { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--brand-strong); text-decoration: none; }
.up-social__grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--space-3); }
.up-social__tile { position: relative; aspect-ratio: 1; border-radius: var(--radius-lg); overflow: hidden; display: block; background: var(--surface-lilac); }
.up-social__tile:nth-child(6n+2) { background: var(--surface-sky); } .up-social__tile:nth-child(6n+3) { background: var(--surface-peach); } .up-social__tile:nth-child(6n+4) { background: var(--surface-blush); } .up-social__tile:nth-child(6n+5) { background: var(--surface-sky); }
.up-social__tile img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--up-dur-slow) var(--up-ease-out); }
.up-social__tile::after { content: ""; position: absolute; inset: 0; background: rgba(43,34,51,.55); opacity: 0; transition: opacity var(--up-dur-base); }
.up-social__tile:hover img { transform: scale(1.06); }
.up-social__tile:hover::after, .up-social__tile:focus-visible::after { opacity: 1; }
.up-social__tile:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.up-social__links { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.up-chip { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 44px; padding: 0 var(--space-4); border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface-raised); color: var(--ink); font-size: 14px; font-weight: 500; text-decoration: none; transition: border-color var(--up-dur-fast), transform var(--up-dur-fast) var(--up-ease-out); }
.up-chip:hover { border-color: var(--brand-strong); transform: translateY(-2px); }
.up-chip:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.up-chip svg { width: 18px; height: 18px; color: var(--brand-strong); }
@media (max-width: 720px) { .up-social__grid { grid-template-columns: repeat(3, 1fr); } }

/* ── Floating dock (WhatsApp + reserva) ── */
.up-dock { position: fixed; right: var(--space-6); bottom: var(--space-6); z-index: var(--z-dock); display: grid; justify-items: end; gap: var(--space-3); }
.up-dock__wa { display: inline-flex; align-items: center; gap: var(--space-2); height: 56px; padding: 0 var(--space-6) 0 var(--space-4); border-radius: var(--radius-pill); background: var(--surface-raised); color: var(--ink); text-decoration: none; font-weight: 600; font-size: 14px; box-shadow: var(--shadow-float); border: 1px solid var(--border); transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-dock__wa:hover { transform: translateY(-3px); }
.up-dock__wa:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.up-dock__ico { width: 36px; height: 36px; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--success); color: var(--surface-raised); }
.up-dock__ico svg { width: 20px; height: 20px; }
.up-dock__pulse { position: absolute; inset: -4px; border-radius: inherit; border: 2px solid var(--success); opacity: 0; animation: up-pulse 2.8s var(--up-ease-out) 1.5s 3; }
@keyframes up-pulse { 0% { opacity: .6; transform: scale(.9); } 100% { opacity: 0; transform: scale(1.25); } }
.up-mobilebar { position: fixed; left: var(--space-3); right: var(--space-3); bottom: var(--space-3); z-index: var(--z-dock); display: none; grid-template-columns: 1fr auto; gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius-pill); background: var(--surface-glass); border: 1px solid var(--border); box-shadow: var(--shadow-float); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); transform: translateY(0); transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-mobilebar .up-btn { border-radius: var(--radius-pill); }
.up-mobilebar.is-hidden { transform: translateY(140%); }
@media (max-width: 720px) {
  .up-mobilebar { display: grid; }
  .up-dock { display: none; }
  /* Tarea 3 — agregado local: el README de FloatingDock pide dejar espacio libre
     abajo igual a la altura de la barra para que no tape contenido; el bundle no
     lo trae. Antes era body{padding-bottom:80px}: dejaba una franja del fondo
     claro del body después del footer oscuro (se veía como un glitch, un corte
     de color antes del final real de la página). Se mueve el espacio al
     padding-bottom del propio footer, que ya es oscuro -- mismo aire reservado,
     sin la franja. (Había subido a 180px para despejar la burbuja de Tidio; se
     vuelve a 80px porque Tidio y los demás plugins de chat se desactivaron.) */
  .up-footer { padding-bottom: 80px; }
}

/* ── Footer ── */
.up-footer { background: var(--surface-inverse); color: var(--ink-inverse); border-radius: var(--radius-xl) var(--radius-xl) 0 0; padding: var(--space-20) 0 var(--space-8); }
.up-footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--space-8); }
.up-footer h4 { margin: 0 0 var(--space-4); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; font-weight: 600; color: var(--ink-inverse-muted); }
.up-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.up-footer a { color: var(--ink-inverse); text-decoration: none; font-size: 15px; }
.up-footer a:hover { text-decoration: underline; text-underline-offset: 4px; }
.up-footer a:focus-visible { outline: 2px solid var(--ink-inverse); outline-offset: 3px; border-radius: 4px; }
.up-footer__logo img { height: 88px; }
.up-footer__txt { color: var(--ink-inverse-muted); font-size: 14px; line-height: 22px; margin: var(--space-4) 0 var(--space-6); max-width: 34ch; }
.up-footer__social { display: flex; gap: var(--space-2); }
.up-footer__social a { width: 44px; height: 44px; border-radius: var(--radius-pill); display: grid; place-items: center; border: 1px solid rgba(246,242,250,.25); transition: background-color var(--up-dur-fast), transform var(--up-dur-fast) var(--up-ease-out); }
.up-footer__social a:hover { background: rgba(246,242,250,.12); transform: translateY(-2px); text-decoration: none; }
.up-footer__social svg { width: 18px; height: 18px; }
.up-footer__legal { margin-top: var(--space-12); padding-top: var(--space-6); border-top: 1px solid rgba(246,242,250,.15); display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-4); font-size: 13px; color: var(--ink-inverse-muted); }
@media (max-width: 880px) { .up-footer__grid { grid-template-columns: 1fr 1fr; } }
/* Bug real reportado: en mobile chico 2 columnas quedaba muy apretado (mucho wrap
   de texto en "Especialidades"/dirección). Una sola columna respira mejor acá. */
@media (max-width: 560px) {
  .up-footer { padding-top: var(--space-12); }
  .up-footer__grid { grid-template-columns: 1fr; gap: var(--space-8); }
  .up-footer__legal { margin-top: var(--space-8); }
}

/* ── Reduced motion: todo queda visible y quieto ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
  .up-motion [data-up-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  [data-up-parallax] { transform: none !important; }
  .up-fx--icon { opacity: var(--o, .6) !important; top: 40% !important; left: 50% !important; transform: scale(1) rotate(0deg) !important; }
}

/* ── Photo frames (fotografía médica y familiar) ── */
.up-photo { position: relative; border-radius: var(--radius-xl); overflow: hidden; background: linear-gradient(160deg, var(--surface-sky), var(--surface-lilac) 55%, var(--surface-blush)); isolation: isolate; }
.up-photo img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 1.2s var(--up-ease-out); }
.up-photo:hover img { transform: scale(1.03); }
.up-photo--tint::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 55%, rgba(43,34,51,.35)); pointer-events: none; }
.up-photo--circle { border-radius: var(--radius-pill); border: 6px solid var(--surface-raised); box-shadow: 0 0 0 2px var(--puzzle-blue), var(--shadow-float); }
.up-photo__ph { position: absolute; inset: 0; display: grid; place-content: center; gap: var(--space-2); padding: var(--space-6); text-align: center; color: var(--ink-muted); font-size: 13px; line-height: 19px; }
.up-photo__ph svg { width: 28px; height: 28px; margin: auto; opacity: .7; }
.up-photo__ph b { color: var(--ink); font-weight: 600; }
.up-hero__photo2 { position: absolute; width: 38%; aspect-ratio: 1; right: -2%; bottom: 8%; }
.up-trust { position: absolute; display: inline-flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-pill); background: var(--surface-glass); border: 1px solid var(--border); box-shadow: var(--shadow-card); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); font-size: 13px; line-height: 18px; font-weight: 500; }
.up-trust b { display: block; font-size: 15px; font-weight: 700; color: var(--brand-strong); }
.up-trust__ico { width: 36px; height: 36px; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--surface-lilac); color: var(--brand-strong); }
.up-trust__ico svg { width: 18px; height: 18px; }

/* ── Banner ── */
.up-banner { position: relative; display: grid; grid-template-columns: 1fr 1.1fr; min-height: 340px; border-radius: var(--radius-xl); overflow: hidden; background: var(--surface-sky); }
.up-banner--blush { background: var(--surface-blush); } .up-banner--lilac { background: var(--surface-lilac); }
.up-banner__copy { position: relative; z-index: 1; display: grid; align-content: center; justify-items: start; gap: var(--space-4); padding: var(--space-12); }
.up-banner__media { position: relative; }
.up-banner__media .up-photo { position: absolute; inset: 0; border-radius: 0; }
.up-banner__media::before { content: ""; position: absolute; z-index: 1; left: -1px; top: 0; bottom: 0; width: 120px; background: linear-gradient(90deg, var(--up-banner-bg, var(--surface-sky)), transparent); pointer-events: none; }
.up-banner--blush { --up-banner-bg: var(--surface-blush); } .up-banner--lilac { --up-banner-bg: var(--surface-lilac); }
.up-banner--reverse { grid-template-columns: 1.1fr 1fr; } .up-banner--reverse .up-banner__media { order: -1; } .up-banner--reverse .up-banner__media::before { left: auto; right: -1px; background: linear-gradient(270deg, var(--up-banner-bg, var(--surface-sky)), transparent); }
@media (max-width: 880px) { .up-banner, .up-banner--reverse { grid-template-columns: 1fr; } .up-banner__media { min-height: 240px; order: -1; } .up-banner__media::before { display: none; } .up-banner__copy { padding: var(--space-8) var(--space-6); } }
.up-hero__media .up-photo { position: absolute; }

/* ── Tabs de especialidad (filtro) ── */
.up-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.up-tab { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 36px; padding: 0 var(--space-4); border-radius: var(--radius-pill); border: 1px solid var(--border); background: var(--surface-raised); color: var(--ink); font: 500 14px/1 var(--font-sans); cursor: pointer; transition: background-color var(--up-dur-fast), border-color var(--up-dur-fast), color var(--up-dur-fast); }
.up-tab:hover { border-color: var(--brand-strong); }
.up-tab[aria-selected="true"] { background: var(--brand-strong); border-color: var(--brand-strong); color: var(--on-brand); }
.up-tab:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.up-tab__dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--up-esp, var(--brand)); }
/* En mobile, envolver 8 pills de ancho variable ("Fisioterapia y Kinesiología")
   arma una lista despareja de una sola columna, larga y sin cara de tabs. Se
   pasa a una tira horizontal con scroll (mismo patrón que .up-specialties en
   mobile) en vez de apilar -- se sigue viendo como una barra de tabs, no como
   una lista. */
@media (max-width: 640px) {
  .up-tabs { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: var(--space-1); scrollbar-width: none; }
  .up-tabs::-webkit-scrollbar { display: none; }
  .up-tab { flex: none; scroll-snap-align: start; }
}

/* ── Profesional ── */
.up-team { display: grid; gap: var(--space-8); }
.up-team__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: var(--space-6); perspective: 1200px; }
/* Mismo tilt 3D por puntero que SpecialtyCard (ver .up-card más arriba), variables en 0deg en reposo. */
.up-pro { --up-esp: var(--brand); display: flex; flex-direction: column; background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); transition: transform var(--up-dur-base) var(--up-ease-out), box-shadow var(--up-dur-base) var(--up-ease-out); }
.up-pro[hidden] { display: none; }
.up-pro:hover { transform: translateY(-4px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); box-shadow: var(--shadow-card); }
/* Mismo bug de especificidad del reveal que .up-card (ver más arriba): sin esto el
   hover-lift de la tarjeta de profesional tampoco se veía nunca. */
.up-motion .up-pro[data-up-reveal].is-in { transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); }
.up-motion .up-pro[data-up-reveal].is-in:hover { transform: translateY(-4px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); }
.up-pro--blue { --up-esp: var(--puzzle-blue); } .up-pro--yellow { --up-esp: var(--puzzle-yellow); } .up-pro--coral { --up-esp: var(--puzzle-coral); } .up-pro--violet { --up-esp: var(--brand); }
.up-pro__media { position: relative; aspect-ratio: 4 / 3.6; }
.up-pro__media .up-photo { position: absolute; inset: 0; border-radius: 0; }
.up-pro__media::after { content: ""; position: absolute; left: var(--space-6); bottom: -14px; width: 28px; height: 28px; border-radius: var(--radius-pill); background: var(--up-esp); border: 4px solid var(--surface-raised); }
.up-pro__body { display: grid; gap: var(--space-2); padding: var(--space-6) var(--space-6) var(--space-4); flex: 1; align-content: start; }
.up-pro__name { margin: 0; font-size: 18px; line-height: 24px; font-weight: 600; letter-spacing: -0.01em; }
.up-pro__role { margin: 0; font-size: 14px; line-height: 20px; color: var(--brand-strong); font-weight: 500; }
.up-pro__reg { margin: 0; font-size: 12px; line-height: 16px; color: var(--ink-muted); }
.up-pro__bio { margin: var(--space-2) 0 0; font-size: 14px; line-height: 22px; color: var(--ink-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.up-pro__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--space-2); }
.up-pro__days { display: flex; gap: 4px; margin-top: var(--space-3); }
.up-pro__day { width: 28px; height: 28px; border-radius: var(--radius-pill); display: grid; place-items: center; font-size: 11px; font-weight: 600; color: var(--ink-muted); background: var(--surface); border: 1px solid var(--border); }
.up-pro__day.on { background: var(--surface-lilac); color: var(--brand-strong); border-color: transparent; }
.up-pro__actions { display: flex; gap: var(--space-2); padding: 0 var(--space-6) var(--space-6); }
.up-pro__actions .up-btn { flex: 1; padding-inline: var(--space-3); }

/* ── Perfil + agenda del profesional ── */
.up-profile { display: grid; grid-template-columns: 340px 1fr; gap: var(--space-12); align-items: start; }
.up-profile__aside { display: grid; gap: var(--space-4); position: sticky; top: 96px; }
.up-profile__photo { aspect-ratio: 4 / 5; }
.up-profile__main { display: grid; gap: var(--space-6); }
.up-profile__list { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--space-2); font-size: 15px; line-height: 24px; }
.up-profile__list li { display: flex; gap: var(--space-2); }
.up-profile__list li::before { content: ""; flex: none; width: 6px; height: 6px; margin-top: 9px; border-radius: var(--radius-pill); background: var(--up-esp, var(--brand)); }
.up-agenda { display: grid; gap: var(--space-4); padding: var(--space-6); border-radius: var(--radius-lg); background: var(--surface-raised); border: 1px solid var(--border); box-shadow: var(--shadow-card); }
.up-agenda__head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); }
.up-agenda__title { margin: 0; font-size: 18px; font-weight: 600; }
.up-agenda__nav { display: flex; gap: var(--space-1); }
.up-agenda__week { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--space-2); }
.up-agenda__day { display: grid; gap: 2px; justify-items: center; padding: var(--space-2) 0; border-radius: var(--radius-md); border: 1.5px solid var(--border); font-size: 12px; color: var(--ink-muted); background: var(--surface-raised); cursor: pointer; font-family: var(--font-sans); }
.up-agenda__day b { font-size: 18px; color: var(--ink); font-weight: 600; }
.up-agenda__day[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.up-agenda__day[aria-selected="true"] { border-color: var(--brand-strong); background: var(--surface-lilac); }
.up-agenda__day:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.up-agenda__note { margin: 0; font-size: 13px; color: var(--ink-muted); }
@media (max-width: 880px) { .up-profile { grid-template-columns: 1fr; } .up-profile__aside { position: static; max-width: 360px; } .up-agenda__week { grid-template-columns: repeat(3, 1fr); } }

/* ── Hero: foto a sangre fundida con velo claro + efectos sutiles ── */
.up-hero--photo { min-height: 640px; display: flex; align-items: center; }
.up-hero--photo .up-hero__grid { grid-template-columns: 1.1fr .9fr; width: min(1200px, 100% - 2 * var(--space-6)); }
.up-hero__bg { position: absolute; inset: -8% 0 -8% 22%; z-index: 0; pointer-events: none; }
.up-hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 60% 40%; display: block; filter: blur(2px) saturate(92%) brightness(1.03); transform: scale(1.04); }
.up-hero__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none; background:
  linear-gradient(90deg, rgba(253,251,250,1) 0%, rgba(253,251,250,.96) 30%, rgba(253,251,250,.78) 48%, rgba(253,251,250,.28) 72%, rgba(253,251,250,.08) 100%),
  linear-gradient(180deg, rgba(239,231,245,.35) 0%, rgba(239,231,245,0) 40%, rgba(253,251,250,0) 75%, var(--surface) 100%); }
.up-hero__fx { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.up-fx { position: absolute; left: var(--x); top: var(--y); }
.up-fx--dot { width: var(--s, 16px); height: var(--s, 16px); border-radius: var(--radius-pill); background: var(--c, var(--puzzle-blue)); opacity: var(--o, .45); animation: up-drift var(--d, 18s) var(--up-ease-in-out) var(--delay, 0s) infinite alternate; }
.up-fx--ring { width: var(--s, 40px); height: var(--s, 40px); border-radius: var(--radius-pill); border: 2px solid var(--c, var(--brand)); opacity: var(--o, .35); animation: up-drift var(--d, 22s) var(--up-ease-in-out) var(--delay, 0s) infinite alternate; }
.up-fx--plus { width: var(--s, 18px); height: var(--s, 18px); color: var(--c, var(--brand)); opacity: var(--o, .4); animation: up-twinkle var(--d, 7s) var(--up-ease-in-out) var(--delay, 0s) infinite; }
.up-fx--plus::before, .up-fx--plus::after { content: ""; position: absolute; left: 50%; top: 50%; background: currentColor; border-radius: 2px; }
.up-fx--plus::before { width: 100%; height: 2px; transform: translate(-50%, -50%); }
.up-fx--plus::after { width: 2px; height: 100%; transform: translate(-50%, -50%); }
@keyframes up-drift { 0% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(var(--dx, 14px), var(--dy, -18px), 0) scale(1.06); } 100% { transform: translate3d(calc(var(--dx, 14px) * -.6), calc(var(--dy, -18px) * .4), 0) scale(.96); } }
@keyframes up-twinkle { 0%, 100% { opacity: calc(var(--o, .4) * .45); transform: scale(.85) rotate(-8deg); } 50% { opacity: var(--o, .4); transform: scale(1.1) rotate(8deg); } }

/* Panel de datos verificables sobre la foto (glass para garantizar contraste) */
.up-hero__aside { position: relative; justify-self: end; display: flex; align-items: center; gap: var(--space-8); }
.up-hero__stats { display: grid; gap: var(--space-6); padding: var(--space-6) var(--space-8); border-radius: var(--radius-lg); background: rgba(253,251,250,.82); border: 1px solid var(--border); box-shadow: var(--shadow-card); backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%); }
.up-hero__stat { display: grid; gap: 2px; padding-left: var(--space-4); border-left: 2px solid var(--c, var(--brand)); }
.up-hero__stat b { font-size: 28px; line-height: 32px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); }
.up-hero__stat span { font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-muted); }
/* Rompecabezas que se arma con el scroll (eco del isotipo).
   --p lo escribe motion.js (data-up-assemble): 0 = piezas dispersas, 1 = armado. Sin JS o con reduced-motion: 1. */
.up-puzzle { --p: 1; position: relative; width: 210px; flex: none; }
.up-puzzle svg { display: block; width: 100%; height: auto; overflow: visible; }
.up-puzzle path { --q: calc(1 - var(--p)); stroke: var(--surface-raised); stroke-width: 4; stroke-linejoin: round; transform-box: fill-box; transform-origin: center;
  translate: calc(var(--sx) * var(--q)) calc(var(--sy) * var(--q)); rotate: calc(var(--sr) * var(--q)); opacity: calc(.55 + .45 * var(--p));
  transition: translate 160ms linear, rotate 160ms linear, opacity 160ms linear; filter: drop-shadow(0 6px 10px rgba(107,74,138,.16)); }
.up-puzzle .pc-tl { fill: var(--puzzle-coral); --sx: -46px; --sy: -92px; --sr: -38deg; --px: -6px; --py: -5px; --pr: -4deg; }
.up-puzzle .pc-tr { fill: var(--brand); --sx: 84px; --sy: -70px; --sr: 30deg; --px: 6px; --py: -5px; --pr: 4deg; --delay: -2.5s; }
.up-puzzle .pc-bl { fill: var(--puzzle-blue); --sx: -34px; --sy: 96px; --sr: 26deg; --px: -5px; --py: 6px; --pr: 3deg; --delay: -5s; }
.up-puzzle .pc-br { fill: var(--puzzle-yellow); --sx: 90px; --sy: 78px; --sr: -34deg; --px: 5px; --py: 6px; --pr: -4deg; --delay: -7.5s; }
/* una vez armado: respiración sutil de las piezas y flotación del conjunto */
.up-puzzle.is-assembled { animation: up-float 8s var(--up-ease-in-out) infinite alternate; }
.up-puzzle.is-assembled path { animation: up-piece 10s var(--up-ease-in-out) var(--delay, 0s) infinite; }
/* Variante del rompecabezas para ParallaxBanner-brand (pedido del cliente: que
   vuelva a aparecer acá, "de otra forma y en otra posición" que en el Hero) --
   más chico, de fondo en una esquina en vez de junto al copy, y con otra
   coreografía de armado (de qué lado vuela cada pieza) para que no sea una
   copia exacta. */
.up-puzzle--alt { position: absolute; width: 130px; right: 6%; bottom: 6%; opacity: .92; }
.up-puzzle--alt .pc-tl { --sx: 60px; --sy: -70px; --sr: 55deg; }
.up-puzzle--alt .pc-tr { --sx: -55px; --sy: 85px; --sr: -50deg; }
.up-puzzle--alt .pc-bl { --sx: 80px; --sy: 40px; --sr: -60deg; }
.up-puzzle--alt .pc-br { --sx: -75px; --sy: -85px; --sr: 65deg; }
@media (max-width: 880px) {
  .up-puzzle--alt { display: none; }
}
@keyframes up-piece { 0%, 35%, 100% { transform: translate(0, 0) rotate(0deg); } 60% { transform: translate(var(--px), var(--py)) rotate(var(--pr)); } }
.up-fx--piece { width: var(--s, 28px); height: var(--s, 28px); color: var(--c, var(--puzzle-blue)); opacity: var(--o, .5); animation: up-drift-rot var(--d, 20s) var(--up-ease-in-out) var(--delay, 0s) infinite alternate; }
.up-fx--piece svg { width: 100%; height: 100%; overflow: visible; display: block; }
.up-fx--piece path { fill: currentColor; }
@keyframes up-drift-rot { 0% { transform: translate3d(0, 0, 0) rotate(-8deg); } 50% { transform: translate3d(var(--dx, 10px), var(--dy, -14px), 0) rotate(6deg); } 100% { transform: translate3d(calc(var(--dx, 10px) * -.5), calc(var(--dy, -14px) * .4), 0) rotate(-3deg); } }

/* Contenedor genérico de círculos decorativos para secciones "de más abajo" que no
   son Hero/ParallaxBanner (esos ya traen su propio .up-hero__fx/.up-pbanner__fx).
   La sección que lo use necesita position:relative + isolation:isolate + overflow:hidden
   (ver #especialidades en page-home.php) para que el z-index negativo no se escape. */
.up-fx-layer { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }

/* Isotipo real (círculo + rompecabezas, wp-content/uploads/.../cropped-UPALALA-BG-OUT.png)
   usado como pieza decorativa -- pedido explícito del cliente, por eso se usa el
   isotipo tal cual en vez de las formas genéricas .up-fx--dot/--piece (el README
   del design system solo cubre el criterio por defecto). Un solo isotipo por
   sección (no varios): traza una curva (no una línea recta) de chico a grande,
   girando y desvaneciéndose hasta desaparecer. Ligado al scroll, no a un loop de
   tiempo (pedido del cliente: "todas las animaciones son en base al scroll") --
   motion.js (data-up-curve) escribe --t (0..1, avance real dentro de la sección)
   y se "scrubbea" el keyframe con animation-delay negativo, reusando la misma
   definición en vez de reimplementar la interpolación en JS. animation-play-state
   paused porque el avance lo controla el delay, no el reloj del navegador.
   --s es el tamaño de partida, --o la opacidad de pico. */
.up-fx--icon { width: var(--s, 48px); height: var(--s, 48px); filter: drop-shadow(0 8px 18px rgba(58,38,82,.2)); animation: up-elevator 1s linear paused; animation-delay: calc(var(--t, 0) * -1s); }
.up-fx--icon img { width: 100%; height: 100%; display: block; border-radius: var(--radius-pill); }
@keyframes up-elevator {
  0%   { top: 4%;  left: 10%; transform: scale(.5)   rotate(0deg);   opacity: 0; }
  10%  { opacity: var(--o, .7); }
  42%  { top: 34%; left: 64%; transform: scale(1.15)  rotate(150deg); opacity: var(--o, .7); }
  74%  { top: 68%; left: 30%; transform: scale(1.8)  rotate(300deg); opacity: var(--o, .55); }
  100% { top: 96%; left: 50%; transform: scale(2.5)  rotate(430deg); opacity: 0; }
}
@media (max-width: 880px) {
  .up-hero--photo { min-height: 0; }
  .up-hero--photo .up-hero__grid { grid-template-columns: 1fr; }
  .up-hero__bg { inset: 0; } .up-hero__bg img { object-position: 70% 30%; }
  .up-hero__veil { background: linear-gradient(180deg, rgba(253,251,250,.75) 0%, rgba(253,251,250,.95) 45%, var(--surface) 100%); }
  .up-hero__aside { justify-self: start; } .up-puzzle { display: none; }
  .up-fx:nth-child(n+5) { display: none; }
}
.up-tab__n { min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill); display: inline-grid; place-items: center; font-size: 11px; font-weight: 600; background: var(--surface-lilac); color: var(--brand-strong); }
.up-tab[aria-selected="true"] .up-tab__n { background: rgba(255,255,255,.22); color: var(--on-brand); }

/* ── Banner intermedio con parallax y mensaje motivador ── */
.up-pbanner { position: relative; isolation: isolate; overflow: hidden; display: grid; align-items: center; min-height: 440px; border-radius: var(--radius-xl); }
.up-pbanner--bleed { border-radius: 0; }
.up-pbanner__bg { position: absolute; inset: -24% 0; z-index: -3; will-change: transform; }
.up-pbanner__bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.up-pbanner__veil { position: absolute; inset: 0; z-index: -2; pointer-events: none; background: linear-gradient(90deg, rgba(253,251,250,.96) 0%, rgba(253,251,250,.9) 40%, rgba(253,251,250,.45) 70%, rgba(253,251,250,.12) 100%); }
.up-pbanner__fx { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.up-pbanner__content { position: relative; display: grid; gap: var(--space-4); justify-items: start; max-width: 620px; padding: var(--space-20) var(--space-12); }
.up-pbanner__msg { margin: 0; font-size: clamp(32px, 4.6vw, 54px); line-height: 1.08; font-weight: 300; letter-spacing: -0.03em; text-wrap: balance; color: var(--ink); }
.up-pbanner__msg em { font-style: normal; font-weight: 600; color: var(--brand-strong); }
.up-pbanner__sub { margin: 0; font-size: 18px; line-height: 29px; color: var(--ink-muted); max-width: 48ch; }
.up-pbanner__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-2); }
/* Subrayado que se dibuja bajo la palabra destacada */
.up-mark { position: relative; z-index: 0; white-space: nowrap; }
.up-mark::after { content: ""; position: absolute; z-index: -1; left: -.06em; right: -.06em; bottom: .04em; height: .3em; border-radius: 6px; background: var(--puzzle-yellow); opacity: .85; transform-origin: left; transition: transform 900ms var(--up-ease-out) 450ms; }
.up-motion [data-up-reveal]:not(.is-in) .up-mark::after { transform: scaleX(0); }
/* Variante de marca: velo violeta profundo, texto claro, centrado */
.up-pbanner--brand .up-pbanner__veil { background: linear-gradient(100deg, rgba(58,38,82,.93) 0%, rgba(74,50,99,.9) 100%); } /* peor caso sobre foto blanca: texto 7.4:1, secundario 4.6:1 */
.up-pbanner--brand .up-pbanner__content { justify-items: center; text-align: center; margin-inline: auto; max-width: 760px; }
.up-pbanner--brand .up-pbanner__msg { color: var(--ink-inverse); }

/* ── Formulario (agregado local: el bundle no trae ningún patrón de formulario,
   necesario para Contacto) — mismos tokens que .up-btn/.lp-option: borde,
   radius-md, foco visible con --focus-ring. */
.up-form { display: grid; gap: var(--space-4); }
.up-form__row { display: grid; gap: var(--space-4); grid-template-columns: 1fr 1fr; }
@media (max-width: 640px) { .up-form__row { grid-template-columns: 1fr; } }
.up-form label { display: block; margin-bottom: var(--space-2); font-size: 13px; font-weight: 600; color: var(--ink-muted); }
.up-form input, .up-form select, .up-form textarea { width: 100%; padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); border: 1.5px solid var(--border); background: var(--surface-raised); color: var(--ink); font-family: var(--font-sans); font-size: 15px; transition: border-color var(--up-dur-fast); }
.up-form input:focus, .up-form select:focus, .up-form textarea:focus { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-color: var(--brand-strong); }
.up-form textarea { resize: vertical; min-height: 120px; }
.up-form__error { display: none; margin-top: var(--space-1); font-size: 13px; color: var(--puzzle-coral); }
.up-form__note { margin: 0; font-size: 13px; color: var(--ink-muted); }
.up-pbanner--brand .up-pbanner__msg em { color: var(--puzzle-yellow); }
.up-pbanner--brand .up-pbanner__sub { color: var(--ink-inverse-muted); }
.up-pbanner--brand .up-mark::after { background: var(--puzzle-coral); opacity: .45; }
.up-pbanner--brand .up-fx--plus { color: #ffffff; }
.up-btn--light { background: #ffffff; color: var(--brand-strong); }
.up-btn--light:hover { box-shadow: 0 10px 24px rgba(0,0,0,.25); }
.up-btn--outline-light { background: transparent; color: var(--ink-inverse); border-color: rgba(246,242,250,.7); }
.up-btn--outline-light:hover { background: rgba(246,242,250,.12); }
.up-pbanner--brand .up-btn:focus-visible { outline-color: #ffffff; }
@media (max-width: 720px) {
  .up-pbanner { min-height: 360px; }
  .up-pbanner__content { padding: var(--space-12) var(--space-6); }
  .up-pbanner__veil { background: linear-gradient(180deg, rgba(253,251,250,.9), rgba(253,251,250,.96)); }
  .up-pbanner .up-fx:nth-child(n+4) { display: none; }
}

/* ── Tarea 3 — agregado local, no está en docs/design-system/components/bundle.css ──
   El README de SiteHeader pide un drawer móvil accesible pero el bundle no trae su
   markup/CSS. Se agrega acá siguiendo los mismos tokens y la convención .up-* para
   no inventar un lenguaje visual nuevo; falta subirlo al design system original. */
.up-header__toggle { display: none; }
@media (max-width: 1024px) {
  .up-header__toggle { display: inline-flex; }
  .up-header__ig { display: none; } /* README: bajo el umbral, drawer + CTA visibles; el Instagram del bar no entra */
}
.up-header__drawer[hidden] { display: none; }
.up-header__drawer { position: fixed; inset: 0; z-index: calc(var(--z-header) + 10); }
.up-header__drawer-backdrop { position: absolute; inset: 0; background: rgba(28,26,34,.45); opacity: 0; transition: opacity var(--up-dur-base) var(--up-ease-out); }
.up-header__drawer.is-open .up-header__drawer-backdrop { opacity: 1; }
.up-header__drawer-panel { position: absolute; top: 0; right: 0; bottom: 0; width: min(340px, 86vw); background: var(--surface-raised); box-shadow: var(--shadow-float); padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-8); border-radius: var(--radius-xl) 0 0 var(--radius-xl); transform: translateX(100%); transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-header__drawer.is-open .up-header__drawer-panel { transform: translateX(0); }
.up-header__drawer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.up-header__drawer-logo { display: block; line-height: 0; }
.up-header__drawer-logo img { height: 36px; width: auto; }
.up-header__drawer-close { transition: transform var(--up-dur-base) var(--up-ease-out), background-color var(--up-dur-fast); }
.up-header__drawer-close:hover { transform: rotate(90deg); }
.up-header__drawer nav { display: flex; flex-direction: column; gap: var(--space-2); }
.up-header__drawer nav a { font-family: var(--font-sans); font-size: 19px; font-weight: 500; color: var(--ink); text-decoration: none; padding: var(--space-2) 0; opacity: 0; transform: translateX(24px); transition: opacity var(--up-dur-base) var(--up-ease-out), transform var(--up-dur-base) var(--up-ease-out), color var(--up-dur-fast), padding-left var(--up-dur-fast) var(--up-ease-out); }
.up-header__drawer.is-open nav a { opacity: 1; transform: translateX(0); }
.up-header__drawer.is-open nav a:nth-child(1) { transition-delay: 90ms; }
.up-header__drawer.is-open nav a:nth-child(2) { transition-delay: 140ms; }
.up-header__drawer.is-open nav a:nth-child(3) { transition-delay: 190ms; }
.up-header__drawer.is-open nav a:nth-child(4) { transition-delay: 240ms; }
.up-header__drawer.is-open nav a:nth-child(5) { transition-delay: 290ms; }
.up-header__drawer nav a:hover { color: var(--brand-strong); padding-left: var(--space-2); }
.up-header__drawer nav a[aria-current="page"] { color: var(--brand-strong); }
.up-header__drawer nav a:focus-visible, .up-header__drawer-close:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 4px; border-radius: 4px; }
.up-header__drawer-book { opacity: 0; transform: translateY(14px); transition: opacity var(--up-dur-base) var(--up-ease-out), transform var(--up-dur-base) var(--up-ease-out); transition-delay: 320ms; }
.up-header__drawer.is-open .up-header__drawer-book { opacity: 1; transform: translateY(0); }
@media (min-width: 1025px) { .up-header__drawer { display: none; } }

/* ── FAQ (.up-faq): no hay componente de acordeón en docs/design-system, se arma
   acá con los mismos tokens que el resto (surface-raised, border, radius-lg) --
   reemplaza el acordeón de Bootstrap (.accordion/.collapse) de page-home.php,
   que quedaba visualmente aparte del resto del sitio ya rediseñado. Abre/cierra
   con grid-template-rows 0fr↔1fr (sin medir scrollHeight por JS) y respeta
   prefers-reduced-motion por la regla global de components.css. */
.up-faq__item { background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.up-faq__q { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-4) var(--space-6); background: none; border: none; text-align: left; font: 600 16px/24px var(--font-sans); color: var(--ink); cursor: pointer; }
.up-faq__q:hover { color: var(--brand-strong); }
.up-faq__q:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.up-faq__chev { flex: none; width: 20px; height: 20px; color: var(--brand-strong); transition: transform var(--up-dur-base) var(--up-ease-out); }
.up-faq__q[aria-expanded="true"] .up-faq__chev { transform: rotate(180deg); }
.up-faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--up-dur-slow) var(--up-ease-out); }
.up-faq__q[aria-expanded="true"] + .up-faq__a { grid-template-rows: 1fr; }
.up-faq__a-inner { overflow: hidden; }
.up-faq__a p { margin: 0; padding: 0 var(--space-6) var(--space-6); color: var(--ink-muted); font-size: 15px; line-height: 26px; }
.up-faq__a a { color: var(--brand-strong); }
