/* ==========================================================================
   AGENDADOR INTELIGENTE 360 — app.css
   Sistema de diseño mobile-first (360px expandiendo hacia arriba). CSS
   escrito a mano, sin utilidades ni framework (ADR-08). Única excepción
   deliberada de Fase 13: Inter vía Google Fonts (link preconnect + swap
   en el <head> de cada vista) para la tipografía "SaaS de grandes ligas"
   que pide el cliente; el stack de sistema queda como fallback inmediato
   mientras carga, así que no hay parpadeo de texto invisible.
   ========================================================================== */

/* ---- 1. Tokens (§13.1, Fase 13 "Motor de Temas"; revisado en el Pivote
   "Palette-Driven UI"). No existe ningún toggle claro/oscuro manual: la UI
   entera depende 100% del color de fondo que elige el dueño del negocio.
   --primario/--acento/--fondo/--texto se sobreescriben por negocio mediante
   un <style> inline (embudo.php, estado.php, resena.php) o en caliente por
   admin.js (aplicarColores, sesión del panel) -- SIEMPRE con el resultado ya
   calculado del Motor de Contraste (luminancia relativa WCAG), nunca con el
   hex crudo, así que el texto nunca queda ilegible sin importar qué tan
   clara u oscura sea la paleta elegida. ---- */
:root {
  --fondo: #F7F8FA;
  /* ---- Motor de Personalización de Marca: --vidrio-boost es el
     multiplicador (0-2) que controla el slider de "Opacidad del
     Glassmorphism" en Settings -- 1 = el diseño por defecto de siempre.
     --superficie/--superficie-alta se derivan de var(--texto) (no de un
     rgb fijo) a propósito: como --texto ya cambia de tinta oscura a clara
     entre modo claro/oscuro, el mismo color-mix() sirve para ambos temas
     sin duplicar reglas -- mismo truco que --agenda-linea, más abajo. ---- */
  --vidrio-boost: 1;
  --superficie: color-mix(in srgb, var(--texto) calc(4% * var(--vidrio-boost)), transparent);
  --superficie-alta: color-mix(in srgb, var(--texto) calc(6.5% * var(--vidrio-boost)), transparent);
  --borde: rgba(17, 24, 39, .10);
  --desenfoque: blur(14px) saturate(150%);
  --desenfoque-fuerte: blur(24px) saturate(160%);

  --texto: #111827;
  --texto-2: #4B5563;
  --texto-3: #6B7280;
  --texto-sutil: #8A8A8E;

  --primario: #111827;
  --acento: #22D3EE;
  --morado: #8B5CF6;
  --exito: #10B981;
  --alerta: #F59E0B;
  --peligro: #EF4444;

  /* ---- Alpha-Channel Theme Engine (§Compact Dashboard, Alpha Theme):
     mismo color que --acento pero descompuesto en canales "r, g, b" --
     el único formato que permite componer rgba(var(--x-rgb), alpha) para
     transparencias reales. admin.js (aplicarColores) reescribe este
     triplete en caliente con hexARgb() cada vez que el negocio cambia su
     color de marca, así que las citas del calendario SIEMPRE citan la
     marca real, nunca este valor por defecto -- éste es solo el fallback
     antes de que cargue la sesión. ---- */
  --acento-rgb: 34, 211, 238;

  /* ---- Variables de marca (personalización por negocio, Fase 13 §3:
     paletas + color_primario/color_secundario). Hoy son solo alias de
     los tokens de arriba, así que no cambian nada por defecto; el punto
     es que una sobreescritura por negocio solo necesita tocar
     --brand-color/--bg-dark/--surface-color aquí y toda la capa
     "premium" (sheets, tiles, píldoras) se adapta sola. ---- */
  --brand-color: var(--acento);
  --brand-rgb: var(--acento-rgb);
  --bg-dark: var(--fondo);
  --surface-color: var(--superficie);
  /* ---- Motor de Temas Inteligente (§Refactor UI/UX Premium, Fase 2):
     estructura de variables "estricta" que pide el motor de contraste --
     alias de los tokens de arriba por defecto, pero aplicarColores() (ver
     admin.js) y los <style> inline de la landing pública (embudo.php/
     estado.php/resena.php) las sobreescriben con el resultado YA calculado
     de la luminancia relativa del color elegido, nunca con el hex crudo.
     --text-on-bg/--text-on-cta son las que garantizan que el texto nunca
     quede ilegible sin importar qué combinación de colores arme el dueño
     del negocio. ---- */
  --bg-site: var(--fondo);
  --bg-panel: var(--superficie);
  --primary-cta: var(--acento);
  --text-on-bg: var(--texto);
  --text-on-cta: var(--primario);
  /* Fase 24 ("Branding Futurista"): acento del halo del Splash Screen --
     .sa-shell la sobreescribe a --sa-acento (superadmin.css) para que el
     Centro de Comando tenga su propio resplandor esmeralda en vez del cian
     del panel de negocio. */
  --admin-splash-acento: var(--acento);

  --e1: 4px;  --e2: 8px;  --e3: 12px; --e4: 16px;
  --e5: 24px; --e6: 32px; --e7: 48px;
  /* Fase 18.1 ("Embudo de Ventas Premium"): separación entre secciones de
     la landing -- deliberadamente más grande que --e7, para que la página
     "respire" como un sitio premium en vez de un panel denso de app. */
  --e8: 64px; --e9: 80px;

  --r-s: 10px; --r-m: 16px; --r-l: 22px; --r-xl: 28px; --r-full: 999px;

  --fuente: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  --t-xs: 12px; --t-s: 14px; --t-m: 16px; --t-l: 20px;
  --t-xl: clamp(24px, 7vw, 32px);
  /* ---- Rediseño Tipográfico de Alta Gama (§Refactor UI/UX Premium, Fase
     1): tokens fluidos exclusivos de tarjetas de métricas/agenda -- más
     conservadores que --t-xl (que también viste avatares, títulos de hoja
     y encabezados de landing) para que el dato numérico nunca "grite" ni
     asfixie la tarjeta en pantallas angostas. ---- */
  --t-num: clamp(1.5rem, 5vw, 2.2rem);
  --t-etiqueta: clamp(.85rem, 3vw, 1rem);

  --tap-min: 48px;
  --transicion: 180ms cubic-bezier(.4, 0, .2, 1);
  --sombra-suave: 0 2px 10px rgba(17, 24, 39, .06);
  --sombra: 0 8px 32px rgba(17, 24, 39, .12);
  --sombra-flotante: 0 12px 28px rgba(17, 24, 39, .16), 0 2px 8px rgba(17, 24, 39, .08);
  /* Fase 21 (§1, "Silicon Valley Overhaul"): reemplaza los border:1px solid
     de tarjetas/eventos por esta sombra casi imperceptible -- el mismo
     truco de Stripe/Linear, la separación la da la luz, no el trazo. */
  --sombra-ultra-suave: 0 4px 24px rgba(17, 24, 39, .04);
  --seguro-abajo: env(safe-area-inset-bottom, 0px);

  /* Paleta "premium" exclusiva de la cuadrícula de Agenda (§7.4, revisada
     en §Motor de Contraste Absoluto). Las líneas son casi invisibles a
     propósito (color-mix sobre --texto, se adapta solo a modo claro/
     oscuro): un lienzo limpio, no una tabla de Excel — la separación la da
     el espacio en blanco, no el trazo.
     §Motor de Contraste Absoluto (auditoría post-mortem): --agenda-celda
     ANTES era un hex fijo por tema (#FFFFFF / #121212 en el bloque
     data-theme="dark" de abajo), una tinta totalmente ajena a --texto/
     --fondo. aplicarColores() (admin.js) SÍ reescribe --texto/--fondo en
     línea cuando el negocio elige una paleta custom -- y una propiedad
     inline gana SIEMPRE sobre cualquier regla de hoja de estilos, con o
     sin :root[data-theme="dark"]. Resultado real y reproducible: negocio
     con fondo custom claro -> --texto queda fijado en tinta oscura; el
     staff activa el toggle de modo oscuro -> --agenda-celda SÍ hereda el
     hex oscuro de la hoja de estilos (nunca fue tocado por JS) pero
     --texto se queda pegado en su tinta oscura -- texto oscuro sobre
     lienzo casi negro, invisible. La cura no es "más !important" (eso solo
     apuntala la misma grieta): es que --agenda-celda deje de vivir en un
     tercer riel independiente y SIEMPRE se derive de --fondo/--texto, la
     misma pareja que ya viaja sincronizada (juntas por tema o juntas por
     JS, nunca una sin la otra) -- así nunca puede desincronizarse de lo
     que sea que --texto esté pintando encima. */
  --agenda-celda: var(--fondo);
  --agenda-celda-alt: color-mix(in srgb, var(--texto) 4%, var(--fondo));
  --agenda-linea: color-mix(in srgb, var(--texto) 5%, transparent);
  --agenda-linea-fuerte: color-mix(in srgb, var(--texto) 9%, transparent);
}

/* ---- data-theme="dark" (Fase 22 §3, "El Centro de Comando"): YA NO es un
   toggle de usuario -- el Pivote "Palette-Driven UI" lo eliminó por completo
   del panel de negocio y de la web pública, donde el color de fondo de la
   paleta manda 100%. Este bloque sobrevive exclusivamente porque
   app/Vistas/superadmin/panel.php fija data-theme="dark" de forma FIJA y
   permanente en <html> -- el Centro de Comando del dueño del SaaS, oscuro
   por diseño, sin paleta de negocio ni alternancia posible. ---- */
:root[data-theme="dark"] {
  --fondo: #0B0F14;
  /* --superficie/--superficie-alta NO se repiten acá: heredan la misma
     fórmula color-mix(var(--texto)...) de :root, y como --texto ya cambió
     a un tono claro arriba, el resultado es un cristal esmerilado blanco
     sobre fondo oscuro sin declarar la regla dos veces. */
  --borde: rgba(255, 255, 255, .10);

  --texto: #F3F4F6;
  --texto-2: #9CA3AF;
  --texto-3: #6B7280;
  --texto-sutil: #A0A0A0;

  --sombra-suave: 0 2px 10px rgba(0, 0, 0, .25);
  --sombra: 0 8px 32px rgba(0, 0, 0, .35);
  --sombra-flotante: 0 12px 28px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);
  --sombra-ultra-suave: 0 4px 24px rgba(0, 0, 0, .22);

  /* --agenda-celda/--agenda-celda-alt NO se repiten acá a propósito (ver
     el comentario largo en :root): ahora se derivan de --fondo/--texto,
     así que heredan solas el cambio de tema sin declarar la regla dos
     veces -- exactamente el mismo criterio que ya usan --superficie/
     --superficie-alta un poco más arriba. */
}

/* ---- 2. Reset mínimo ---- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--fuente);
  font-size: var(--t-m);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
  /* Motor de Temas Inteligente: cuando aplicarColores() reescribe --fondo/
     --texto en caliente (previsualización de marca, antes de guardar), el
     cambio se funde en vez de "parpadear" -- misma regla estricta de
     transición que pide el sistema de settings en todos los cambios de color. */
  transition: background-color .3s ease, color .3s ease;
}
img { max-width: 100%; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* [hidden] debe ganar siempre, sin importar qué tan específico sea un
   componente (reserva.js oculta pantallas/barra/acción con .hidden). */
[hidden] { display: none !important; }

/* ---- 3. Estructura general ---- */
/* Fase 20 (§3, "Revolución App-Like"): 480px fuerza una vista de Aplicación
   en cualquier pantalla, incluso escritorio -- el cliente público nunca ve
   una landing "web" de scroll infinito, siempre un micro-site tipo app. */
.app-shell {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  position: relative;
}

.encabezado {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  background: var(--superficie-alta);
  -webkit-backdrop-filter: var(--desenfoque);
  backdrop-filter: var(--desenfoque);
  border-bottom: 1px solid var(--borde);
}
.encabezado__logo {
  width: 36px; height: 36px; border-radius: var(--r-s);
  background: var(--acento); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--text-on-cta); font-size: var(--t-s);
  overflow: hidden;
}
.encabezado__logo img { width: 100%; height: 100%; object-fit: cover; }
.encabezado__info { min-width: 0; flex: 1; }
.encabezado__nombre {
  font-size: var(--t-m); font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.encabezado__estado { font-size: var(--t-xs); color: var(--texto-2); }
.encabezado__estado.abierto { color: var(--exito); }

.barra-progreso {
  display: flex; gap: var(--e2);
  padding: var(--e3) var(--e4) 0;
}
.barra-progreso__segmento {
  flex: 1; height: 4px; border-radius: var(--r-full);
  background: var(--borde); overflow: hidden;
}
.barra-progreso__segmento.activo, .barra-progreso__segmento.completo {
  background: var(--acento);
}

.pantalla {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--e4) var(--e4) calc(var(--e7) + var(--seguro-abajo) + 72px);
  gap: var(--e4);
}
.pantalla__titulo { font-size: var(--t-l); font-weight: 700; }
.pantalla__subtitulo { font-size: var(--t-s); color: var(--texto-2); }

/* ---- 4. Paso 1 · Catálogo de servicios (upsell visual) ----
   Tarjetas grandes estilo carrusel/Instagram: la imagen vende, el texto
   informa. Sin imagen -> degradado elegante derivado de los tokens. */
.catalogo-servicios {
  display: flex;
  flex-direction: column;
  gap: var(--e4);
}

.tarjeta-servicio {
  position: relative;
  border-radius: var(--r-l);
  overflow: hidden;
  border: 1px solid var(--borde);
  background: var(--superficie);
  box-shadow: var(--sombra);
  text-align: left;
  padding: 0;
  transition: transform var(--transicion), box-shadow var(--transicion);
  -webkit-tap-highlight-color: transparent;
}
.tarjeta-servicio:active { transform: scale(.98); }
@media (prefers-reduced-motion: reduce) {
  .tarjeta-servicio { transition: none; }
  .tarjeta-servicio:active { transform: none; }
}

.tarjeta-servicio__media {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--degradado, linear-gradient(135deg, var(--primario), var(--acento)));
}
.tarjeta-servicio__media img {
  width: 100%; height: 100%; object-fit: cover;
}
.tarjeta-servicio__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, .65) 100%);
}
.tarjeta-servicio__inicial {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 48px; font-weight: 800; color: rgba(255, 255, 255, .85);
  text-shadow: 0 2px 12px rgba(0, 0, 0, .25);
}
.tarjeta-servicio__insignia {
  position: absolute; top: var(--e3); right: var(--e3); z-index: 2;
  background: rgba(17, 24, 39, .72);
  color: #fff;
  font-size: var(--t-xs); font-weight: 600;
  padding: var(--e1) var(--e3);
  border-radius: var(--r-full);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.tarjeta-servicio__overlay {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: var(--e3) var(--e4);
  color: #fff;
}
.tarjeta-servicio__nombre {
  font-size: var(--t-l); font-weight: 700;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .4);
}
.tarjeta-servicio__meta {
  display: flex; align-items: center; gap: var(--e2);
  font-size: var(--t-s); color: rgba(255, 255, 255, .9);
  margin-top: var(--e1);
}
.tarjeta-servicio__meta .punto { opacity: .6; }

.tarjeta-servicio__cuerpo {
  padding: var(--e3) var(--e4) var(--e4);
  display: flex; flex-direction: column; gap: var(--e1);
}
.tarjeta-servicio__descripcion {
  font-size: var(--t-s); color: var(--texto-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tarjeta-servicio__precio {
  font-size: var(--t-l); font-weight: 700; color: var(--acento);
}

/* ---- Fase 16 (§2, CASO 1 "Booking Wizard"): variante ultra-limpia del
   paso 1 para negocios en Plan Básico -- filas de texto, sin fotos ni
   catálogo de marketing. Mismo <button data-servicio-id> que la tarjeta
   Pro, así que reserva.js no necesita ninguna rama nueva para manejarla. ---- */
.catalogo-servicios--simple { gap: var(--e2); }
.tarjeta-servicio--simple {
  display: flex; align-items: center; gap: var(--e3);
  min-height: var(--tap-min);
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-m);
  padding: var(--e3) var(--e4);
  box-shadow: none;
}
.tarjeta-servicio--simple__nombre { flex: 1; min-width: 0; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tarjeta-servicio--simple__meta { flex-shrink: 0; font-size: var(--t-xs); color: var(--texto-2); }
.tarjeta-servicio--simple__flecha { flex-shrink: 0; color: var(--texto-3); font-size: var(--t-l); }

/* ---- Fase 16 (§2, CASO 2 "Catálogo Instagram"): teaser de fotos en la
   bienvenida de negocios Pro -- antesala del catálogo completo del paso 1. ---- */
.vitrina-fotos { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--e2); }
.vitrina-fotos img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-m); }

/* ---- Fase 16 (§3, "Diseño y Confianza"): glassmorphism reutilizable para
   piezas flotantes del embudo público (Modo Express, insignias). Mismo
   var(--desenfoque) que ya usa .encabezado -- ninguna variable nueva. ---- */
.tarjeta-glass {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  box-shadow: var(--sombra);
  padding: var(--e5) var(--e4);
}
.tarjeta-express {
  margin: auto 0; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: var(--e3);
}
.tarjeta-express .boton { max-width: 360px; }
.insignia-confianza {
  display: flex; align-items: flex-start; gap: var(--e2);
  font-size: var(--t-xs); color: var(--texto-2); line-height: 1.5;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-m);
  padding: var(--e3);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
}
.insignia-confianza__icono { flex-shrink: 0; font-size: var(--t-m); line-height: 1.5; }
.insignia-confianza strong { color: var(--texto); }

/* ---- 5. Paso 2 · Recursos ---- */
.fila-recursos {
  display: flex; gap: var(--e3);
  overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: var(--e2); margin: 0 calc(var(--e4) * -1); padding-inline: var(--e4);
}
.chip-recurso {
  scroll-snap-align: start;
  flex: 0 0 auto; width: 108px;
  display: flex; flex-direction: column; align-items: center; gap: var(--e2);
  padding: var(--e3);
  border-radius: var(--r-m);
  border: 1px solid var(--borde);
  background: var(--superficie);
  min-height: var(--tap-min);
}
.chip-recurso.seleccionado { border-color: var(--acento); background: var(--superficie-alta); }
.chip-recurso__avatar {
  width: 56px; height: 56px; border-radius: var(--r-full);
  background: linear-gradient(135deg, var(--primario), var(--acento));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; overflow: hidden;
}
.chip-recurso__avatar img { width: 100%; height: 100%; object-fit: cover; }
.chip-recurso__nombre { font-size: var(--t-xs); text-align: center; }
.chip-recurso__recomendado {
  font-size: 10px; color: var(--acento); font-weight: 700; text-transform: uppercase;
}

/* ---- 6. Paso 3 · Tira de fechas ---- */
.tira-fechas {
  display: flex; gap: var(--e2);
  overflow-x: auto; scroll-snap-type: x mandatory;
  margin: 0 calc(var(--e4) * -1); padding: 0 var(--e4) var(--e2);
}
.pildora-fecha {
  scroll-snap-align: start;
  flex: 0 0 auto; width: 60px; min-height: var(--tap-min);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--e1);
  border-radius: var(--r-m);
  border: 1px solid var(--borde);
  background: var(--superficie);
}
.pildora-fecha__dia { font-size: var(--t-xs); color: var(--texto-2); text-transform: capitalize; }
.pildora-fecha__numero { font-size: var(--t-l); font-weight: 700; }
.pildora-fecha__punto { width: 6px; height: 6px; border-radius: var(--r-full); background: var(--texto-3); }
.pildora-fecha__punto.verde { background: var(--exito); }
.pildora-fecha__punto.ambar { background: var(--alerta); }
.pildora-fecha.seleccionada { border-color: var(--acento); background: var(--superficie-alta); }
.pildora-fecha[aria-disabled="true"] { opacity: .35; text-decoration: line-through; }

/* ---- 7. Paso 4 · Horas ---- */
.encabezado-adhesivo {
  position: sticky; top: 0;
  font-size: var(--t-s); font-weight: 700; color: var(--texto-2);
  background: var(--fondo); padding: var(--e2) 0;
}
.grilla-horas {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e2);
}
.chip-hora {
  min-height: var(--tap-min);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border-radius: var(--r-full); border: 1px solid var(--borde);
  background: var(--superficie); font-size: var(--t-s); font-weight: 600;
  padding: var(--e2);
  transition: background var(--transicion), color var(--transicion), border-color var(--transicion), transform var(--transicion), box-shadow var(--transicion);
}
.chip-hora:active { transform: scale(.94); }
.chip-hora__cupos { font-size: 10px; color: var(--texto-2); font-weight: 400; }
.chip-hora.seleccionada {
  border-color: transparent; background: var(--brand-color); color: var(--text-on-cta); font-weight: 700;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--brand-color) 40%, transparent);
}
.chip-hora.seleccionada .chip-hora__cupos { color: color-mix(in srgb, var(--text-on-cta) 70%, transparent); }

/* ---- 8. Formulario (paso 5) ---- */
.campo { display: flex; flex-direction: column; gap: var(--e1); }
.campo label { font-size: var(--t-s); font-weight: 600; }
.campo input, .campo textarea, .campo select {
  min-height: var(--tap-min);
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-s);
  padding: var(--e3);
  font-size: 16px; /* nunca menor a 16px: evita el zoom automático de iOS */
  color: var(--texto);
}
.campo textarea { min-height: 88px; resize: vertical; }
.campo input:focus, .campo textarea:focus, .campo select:focus {
  outline: 2px solid var(--acento); outline-offset: 1px;
}
.campo__error { font-size: var(--t-xs); color: var(--peligro); display: none; }
.campo.invalido input, .campo.invalido textarea, .campo.invalido select { border-color: var(--peligro); }
.campo.invalido .campo__error { display: block; }
.campo__contador { font-size: var(--t-xs); color: var(--texto-3); text-align: right; }

/* ---- 8.1 Micro-editor rich text (Site Builder → "Nosotros/autoridad") ----
   Vanilla JS + contenteditable, cero librerías (ADR-08). Floating toolbar
   glassmorphism minimalista (mismos tokens --superficie-alta/--desenfoque
   que el resto del panel) para no saturar el formulario; el contenteditable
   reutiliza la misma piel visual que .campo textarea para no desentonar. */
.rte { display: flex; flex-direction: column; gap: var(--e2); }
.rte__toolbar {
  display: inline-flex; align-self: flex-start; gap: 2px;
  padding: 3px;
  border-radius: var(--r-full);
  background: var(--superficie-alta);
  border: 1px solid var(--borde);
  -webkit-backdrop-filter: var(--desenfoque);
  backdrop-filter: var(--desenfoque);
}
.rte__boton {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: var(--r-full);
  border: none; background: transparent; color: var(--texto-2);
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.rte__boton:hover { background: var(--superficie); color: var(--texto); }
.rte__boton--activo { background: var(--acento); color: var(--text-on-cta); }
.rte__editor {
  min-height: 140px;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-s);
  padding: var(--e3);
  font-size: 16px; /* nunca menor a 16px: evita el zoom automático de iOS */
  color: var(--texto);
  line-height: 1.6;
  overflow-y: auto;
}
.rte__editor:focus { outline: 2px solid var(--acento); outline-offset: 1px; }
.rte__editor p { margin: 0 0 .8em; }
.rte__editor p:last-child, .rte__editor ul:last-child { margin-bottom: 0; }
.rte__editor ul { margin: 0 0 .8em; padding-left: 1.2em; }
.rte__editor--vacio::before {
  content: attr(data-placeholder);
  color: var(--texto-3);
  pointer-events: none;
}
.telefono-envoltorio { display: flex; align-items: center; gap: var(--e2); }
.telefono-prefijo {
  min-height: var(--tap-min); display: flex; align-items: center;
  padding: 0 var(--e3); border: 1px solid var(--borde); border-radius: var(--r-s);
  background: var(--superficie); font-weight: 700;
}
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.check-politica { display: flex; align-items: flex-start; gap: var(--e2); font-size: var(--t-s); }
.check-politica input { width: 20px; height: 20px; margin-top: 2px; flex-shrink: 0; }

/* ---- 9. Resumen (paso 6) ---- */
.tarjeta-resumen {
  border: 1px solid var(--borde); border-radius: var(--r-l);
  background: var(--superficie); padding: var(--e4);
  display: flex; flex-direction: column; gap: var(--e3);
}
.resumen-fila { display: flex; justify-content: space-between; gap: var(--e3); font-size: var(--t-s); }
.resumen-fila__valor { font-weight: 600; text-align: right; }
.aviso-politica {
  font-size: var(--t-xs); color: var(--texto-2);
  background: var(--superficie-alta); border-radius: var(--r-s); padding: var(--e3);
}

/* ---- 10. Barra de acción fija (zona del pulgar) ---- */
.accion-fija {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  max-width: 480px; margin: 0 auto;
  padding: var(--e3) var(--e4) calc(var(--e4) + var(--seguro-abajo));
  background: var(--superficie-alta);
  -webkit-backdrop-filter: var(--desenfoque);
  backdrop-filter: var(--desenfoque);
  border-top: 1px solid var(--borde);
  display: flex; gap: var(--e3);
  opacity: 1; transform: translateY(0);
  transition: opacity var(--transicion), transform var(--transicion);
}
/* Fase 19 ("High-Ticket Funnel"): en el paso 0 (bienvenida), la barra fija
   arranca oculta -- el widget de reserva (SECCIÓN 3, embudo.php) ya trae
   su propio CTA "Reservar mi cita" a la vista. reserva.js usa un
   IntersectionObserver sobre ese botón y solo quita esta clase (revela la
   barra) cuando el usuario hace scroll y el CTA original sale del
   viewport: nunca dos botones gigantes compitiendo a la vez. */
.accion-fija.accion-fija--esperando { opacity: 0; transform: translateY(16px); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .accion-fija { transition: none; } }
.boton {
  min-height: 52px;
  width: 100%;
  border-radius: var(--r-m);
  border: 1px solid transparent;
  font-size: var(--t-m); font-weight: 700;
  display: flex; align-items: center; justify-content: center; gap: var(--e2);
  transition: opacity var(--transicion), transform var(--transicion), box-shadow var(--transicion), background var(--transicion), color var(--transicion);
}
/* Dentro de la barra fija (fila), los botones sí deben repartirse el ancho. */
.accion-fija .boton { flex: 1; width: auto; }
.boton:active { transform: scale(.97); }
/* Fase 26 (Pivote Vertical Belleza): estados pronunciados "estilo Apple" --
   el filter:brightness plano no bastaba para que un botón se sintiera con
   peso físico. Ahora el primario levanta (translateY) y profundiza su
   sombra al pasar el mouse, y se "hunde" visiblemente al presionar
   (brightness reducido + sombra recogida), en vez de solo escalar. */
@media (hover: hover) {
  .boton-primario:hover { transform: translateY(-2px); box-shadow: 0 10px 28px color-mix(in srgb, var(--brand-color) 42%, transparent); filter: brightness(1.05); }
  .boton-exito:hover, .boton-peligro:hover { filter: brightness(1.05); }
  .boton-secundario:hover { background: var(--borde); }
}
.boton-primario:active { filter: brightness(.94); box-shadow: 0 3px 10px color-mix(in srgb, var(--brand-color) 30%, transparent); }
.boton-primario { background: linear-gradient(180deg, color-mix(in srgb, var(--brand-color) 100%, white 8%), var(--brand-color)); color: var(--text-on-cta); box-shadow: 0 6px 18px color-mix(in srgb, var(--brand-color) 30%, transparent); }
.boton-secundario { background: var(--superficie-alta); border-color: var(--borde); color: var(--texto); }
.boton-texto { background: none; border: none; color: var(--acento); font-weight: 600; min-height: var(--tap-min); }
.boton-exito { background: var(--exito); color: #06281B; box-shadow: 0 6px 18px color-mix(in srgb, var(--exito) 30%, transparent); }
.boton-peligro { background: var(--peligro); color: #2B0A0A; box-shadow: 0 6px 18px color-mix(in srgb, var(--peligro) 30%, transparent); }
.boton[disabled] { opacity: .5; pointer-events: none; }
.boton-volver {
  width: 44px; height: 44px; border-radius: var(--r-full);
  background: var(--superficie); border: 1px solid var(--borde);
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}

/* ---- 11. Estados: vacío, esqueleto, éxito ---- */
.estado-vacio { text-align: center; color: var(--texto-2); padding: var(--e6) var(--e4); font-size: var(--t-s); }

.esqueleto {
  border-radius: var(--r-m);
  background: linear-gradient(90deg, var(--superficie) 25%, var(--superficie-alta) 37%, var(--superficie) 63%);
  background-size: 400% 100%;
  animation: brillo 1.4s ease infinite;
}
@keyframes brillo { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
@media (prefers-reduced-motion: reduce) { .esqueleto { animation: none; } }

.pantalla-exito { align-items: center; text-align: center; gap: var(--e5); padding-top: var(--e6); }
.marca-exito {
  width: 88px; height: 88px; border-radius: var(--r-full);
  background: var(--exito); display: flex; align-items: center; justify-content: center;
  animation: aparecer 400ms cubic-bezier(.4, 0, .2, 1);
}
.marca-exito svg { width: 44px; height: 44px; }
@keyframes aparecer { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .marca-exito { animation: none; } }
.codigo-reserva {
  font-size: var(--t-xl); font-weight: 800; letter-spacing: .08em;
  background: var(--superficie); border: 1px dashed var(--borde);
  border-radius: var(--r-m); padding: var(--e3) var(--e4);
  display: flex; align-items: center; gap: var(--e3);
}

.temporizador { font-size: var(--t-l); font-weight: 700; color: var(--alerta); }
.dato-pago {
  display: flex; justify-content: space-between; align-items: center; gap: var(--e3);
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-s);
  padding: var(--e3);
}

/* ---- 12. Expansión desde 360px hacia arriba ---- */
@media (min-width: 420px) {
  .grilla-horas { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 640px) {
  .pantalla { padding-left: var(--e6); padding-right: var(--e6); }
  .tarjeta-servicio__nombre { font-size: var(--t-xl); }
}

/* ==========================================================================
   PANEL ADMIN (§7). Premisa de diseño: se usa de pie, con una sola mano.
   Todo a un toque, acciones en hojas inferiores (bottom sheets), nunca en
   una pantalla nueva. Reutiliza los mismos tokens que el embudo público.
   ========================================================================== */

.admin-body { background: var(--fondo); }
.admin-shell { max-width: 720px; margin: 0 auto; min-height: 100vh; position: relative; }

/* ---- Splash Screen (Fase 24, "Branding Futurista") ----
   Pantalla de arranque nativa en CSS/JS: visible desde el primer pixel
   pintado (nada de FOUC de un login en blanco) hasta que admin.js resuelve
   la sesión Y se cumple una duración mínima -- lo que tarde más, el mismo
   criterio de Notion/Linear, para que nunca desaparezca antes de que el
   panel esté listo detrás, pero tampoco parpadee en una conexión rápida
   (ver ocultarSplash() en admin.js/superadmin.js).
   Genérico a propósito: /admin y /superadmin comparten este único bloque y
   solo difieren en qué acento hereda el <svg> -- el gradiente del anillo
   usa var(--acento)/var(--morado) dentro de .admin-shell y
   var(--sa-acento)/var(--sa-acento-2) dentro de .sa-shell (ver el style
   inline de cada <stop> en panel.php), así el mismo componente basta para
   diferenciar visualmente ambas PWA sin duplicar una sola línea de CSS. ---- */
.admin-splash {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--e4);
  background: radial-gradient(120% 100% at 50% 0%, #182036 0%, #0B1120 60%, #070A12 100%);
  transition: opacity 420ms ease, visibility 420ms ease;
}
.admin-splash--oculto { opacity: 0; pointer-events: none; }
.admin-splash__halo {
  position: absolute; width: 220px; height: 220px; border-radius: 50%;
  /* --admin-splash-acento (definida abajo en :root, sobreescrita a
     --sa-acento dentro de .sa-shell en superadmin.css) para que el halo
     también cambie de cian a esmeralda en /superadmin -- si esto usara
     var(--acento) a secas, el halo se quedaría cian ahí porque --acento es
     un token global, no algo que .sa-shell reemplace. */
  background: radial-gradient(circle, color-mix(in srgb, var(--admin-splash-acento) 35%, transparent) 0%, transparent 70%);
  filter: blur(20px);
  animation: admin-splash-halo 2.4s ease-in-out infinite;
}
.admin-splash__logo {
  position: relative;
  animation: admin-splash-marca-in 640ms cubic-bezier(.16, 1, .3, 1) both;
}
.admin-splash__logo-anillo {
  /* El stroke con degradado (url(#admin-splash-grad)) se fija inline en el
     <circle> de panel.php, NO aquí: un url() de fragmento dentro de una
     hoja de estilos EXTERNA se resuelve contra la URL de esa hoja (app.css),
     no contra el documento HTML -- el navegador nunca encuentra el
     <linearGradient> y el anillo queda invisible. Inline sí resuelve contra
     el documento, que es donde vive el <defs>.
     Sin transform-origin a propósito: el círculo ya trae su propio centro
     de rotación embebido en el atributo transform="rotate(-90 32 32)" del
     <circle> (panel.php) -- declarar transform-origin aquí (aunque nada en
     este bloque anime transform; "respirar" solo anima opacity) hace que el
     navegador reancle esa rotación a un origen distinto del (32,32)
     embebido y el arco termina rotado fuera de donde debería, invisible. */
  animation:
    admin-splash-dibujar 1000ms 150ms cubic-bezier(.4, 0, .2, 1) both,
    admin-splash-respirar 2.4s 1150ms ease-in-out infinite;
}
.admin-splash__logo-punto {
  opacity: 0;
  transform-origin: center;
  animation: admin-splash-punto-in 420ms 760ms ease-out both;
}
.admin-splash__marca {
  margin: 0; font-size: var(--t-s); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  animation: admin-splash-texto-in 500ms 480ms ease-out both;
}
@keyframes admin-splash-marca-in { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: scale(1); } }
@keyframes admin-splash-dibujar { from { stroke-dasharray: 0 113.1; } to { stroke-dasharray: 84.8 28.3; } }
@keyframes admin-splash-respirar { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@keyframes admin-splash-punto-in { from { opacity: 0; transform: scale(.3); } to { opacity: 1; transform: scale(1); } }
@keyframes admin-splash-texto-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes admin-splash-halo { 0%, 100% { opacity: .5; transform: scale(1); } 50% { opacity: .85; transform: scale(1.08); } }
@media (prefers-reduced-motion: reduce) {
  .admin-splash, .admin-splash__logo, .admin-splash__logo-anillo, .admin-splash__logo-punto, .admin-splash__marca, .admin-splash__halo {
    animation: none;
  }
  .admin-splash__logo, .admin-splash__logo-punto, .admin-splash__marca { opacity: 1; }
  .admin-splash__logo-anillo { stroke-dasharray: 84.8 28.3; }
}

/* ---- Login ---- */
.admin-login {
  min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: var(--e4);
}
.admin-login__tarjeta {
  width: 100%; max-width: 360px;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-l);
  padding: var(--e5); display: flex; flex-direction: column; gap: var(--e4);
}
.admin-login__tarjeta h1 { font-size: var(--t-xl); }

/* ---- Registro SaaS (Fase 7, onboarding B2B): /registro reutiliza los
   tokens del embudo público, más el selector visual de industria. Sin
   JS de estado: la tarjeta seleccionada se resuelve con :has(:checked). ---- */
.registro-shell {
  max-width: 480px; margin: 0 auto; min-height: 100vh;
  display: flex; flex-direction: column;
  padding: var(--e5) var(--e4) calc(var(--e7) + var(--seguro-abajo));
  gap: var(--e5);
  position: relative; z-index: 1; /* por encima de .registro-fondo (§Fase 25) */
}

/* ---- Fase 25 (§3, "Onboarding Profiling"): halos de luz fijos detrás del
   wizard -- glassmorphism sutil, no un efecto vistoso: dos manchas de
   color muy desenfocadas y a baja opacidad, apenas perceptibles, que le
   dan profundidad al fondo plano para que la tarjeta de cristal de abajo
   (.registro-tarjeta) tenga algo real detrás que desenfocar. Estáticos
   (sin animación) para no competir con la atención del formulario. ---- */
.registro-fondo {
  position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
}
.registro-fondo__halo {
  position: absolute; border-radius: var(--r-full); filter: blur(90px); opacity: .22;
}
.registro-fondo__halo--1 { width: 380px; height: 380px; top: -140px; left: -120px; background: var(--acento); }
.registro-fondo__halo--2 { width: 420px; height: 420px; bottom: -160px; right: -140px; background: var(--morado); }

.registro-marca { font-size: var(--t-s); font-weight: 700; color: var(--acento); text-transform: uppercase; letter-spacing: .04em; }

/* ---- Fase 25: el <form> mismo es una tarjeta de cristal -- antes el
   wizard flotaba directo sobre el fondo plano de la página, sin ningún
   límite visual; ahora cada paso vive dentro de un panel con blur real
   sobre los halos de .registro-fondo (mismo --desenfoque que ya usa el
   TopBar del panel admin), borde apenas visible y una sombra grande y
   suave -- la sensación "flotante" típica del onboarding premium
   (Linear, Stripe, Vercel) en vez de un formulario plano de toda la vida. ---- */
/* Fase 26 (Pivote Vertical Belleza, "Onboarding de Autoridad"): auditoría de
   contraste -- la tarjeta usaba --superficie-alta (6% de tinte), el mismo
   token discreto a propósito para paneles internos, pero sobre los halos
   de color de .registro-fondo eso la volvía casi invisible y arrastraba
   consigo botones/inputs que se leían "planos". Aquí la tarjeta pasa a un
   fondo casi opaco propio (--registro-superficie) + una sombra de dos capas
   (contacto ancho y difuso + una más cerrada) y un filo superior con
   degradado de marca -- el tratamiento "flotante premium" que sí se nota
   encima de cualquier fondo, sin tocar --superficie-alta global (el panel
   admin la sigue usando tal cual).
   Pivote "Palette-Driven UI": --registro-superficie/--registro-campo ya no
   viven en un bloque data-theme="dark" aparte -- se derivan con color-mix()
   de --fondo/--texto, exactamente igual que --superficie/--agenda-celda más
   arriba, así que se funden solos con cualquier paleta (clara u oscura) sin
   declarar la regla dos veces. El realce interior superior sigue siendo un
   blanco fijo de baja opacidad a propósito: es un brillo de cristal (luz
   entrando por arriba), no texto -- no necesita invertirse con la paleta. */
.registro-tarjeta {
  --registro-superficie: color-mix(in srgb, var(--fondo) 85%, transparent);
  --registro-campo: color-mix(in srgb, var(--fondo) 92%, var(--texto) 8%);
  background: var(--registro-superficie);
  -webkit-backdrop-filter: var(--desenfoque);
  backdrop-filter: var(--desenfoque);
  border: 1px solid color-mix(in srgb, var(--borde) 100%, var(--texto) 12%);
  border-radius: var(--r-xl);
  padding: var(--e5) var(--e4);
  box-shadow: 0 32px 64px -20px rgba(17, 24, 39, .28), var(--sombra), inset 0 1px 0 rgba(255, 255, 255, .18);
  position: relative;
  overflow: hidden;
}
/* Filo superior con degradado de marca -- la firma visual "premium" que
   distingue la tarjeta de un formulario plano cualquiera. */
.registro-tarjeta::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--acento), var(--morado));
}
/* Los inputs vivían con --superficie (3.5% de tinte): dentro de una
   tarjeta ya casi opaca necesitan su propio fondo sólido para no
   camuflarse con el marco que los contiene. */
.registro-tarjeta .campo input,
.registro-tarjeta .campo textarea,
.registro-tarjeta .campo select {
  background: var(--registro-campo);
  border-color: color-mix(in srgb, var(--borde) 100%, var(--texto) 14%);
  box-shadow: inset 0 1px 2px rgba(17, 24, 39, .04);
}
.registro-tarjeta .campo input:focus,
.registro-tarjeta .campo textarea:focus,
.registro-tarjeta .campo select:focus {
  border-color: var(--acento);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 22%, transparent);
}

.selector-industria { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e3); }
/* Fase 26 (Pivote Vertical Belleza): el selector de industria del Paso 2
   pasó de 4 opciones (2x2) a 3 (Barbería / Spa de Belleza / Peluquería) --
   3 columnas en vez de 2 evita que la tercera tarjeta quede sola en una
   fila a medio ancho; en pantallas angostas colapsa a 1 columna, como
   cualquier grid de tarjetas del sistema. */
.selector-industria--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 420px) {
  .selector-industria--3 { grid-template-columns: 1fr; }
}
.tarjeta-industria {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--e2);
  padding: var(--e4) var(--e2); min-height: 96px;
  border-radius: var(--r-m); border: 1px solid color-mix(in srgb, var(--borde) 100%, var(--texto) 8%);
  background: var(--registro-campo, var(--superficie)); text-align: center;
  box-shadow: 0 2px 8px rgba(17, 24, 39, .05);
  transition: var(--transicion);
}
.tarjeta-industria input {
  position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer;
}
/* Micro-interacción que faltaba (auditoría §Fase 25): antes solo existía
   el estado ":checked", así que en escritorio (mouse) la tarjeta no daba
   ninguna señal de ser interactiva hasta hacer click -- ahora "invita" al
   pase del cursor antes de decidir, igual que el resto de tarjetas/chips
   del sistema (.chip-hora, .meta-chip). Excluida la ya seleccionada para
   no competir con su propio estado "activo". */
@media (hover: hover) {
  .tarjeta-industria:not(:has(input:checked)):hover {
    border-color: color-mix(in srgb, var(--acento) 50%, var(--borde));
    transform: translateY(-3px);
    box-shadow: 0 10px 24px -8px color-mix(in srgb, var(--acento) 30%, transparent);
  }
}
.tarjeta-industria:has(input:checked) {
  border-color: var(--acento);
  background: color-mix(in srgb, var(--acento) 10%, var(--registro-campo, var(--superficie-alta)));
  box-shadow: 0 0 0 2px var(--acento), 0 10px 24px -8px color-mix(in srgb, var(--acento) 40%, transparent);
  transform: translateY(-1px);
}
.tarjeta-industria:active { transform: scale(.97); }
.tarjeta-industria:has(input:focus-visible) { outline: 2px solid var(--acento); outline-offset: 2px; }
.tarjeta-industria__icono { font-size: 26px; }
.tarjeta-industria__nombre { font-size: var(--t-s); font-weight: 600; }
.registro-pie { text-align: center; font-size: var(--t-s); color: var(--texto-2); }
.registro-pie a { color: var(--acento); font-weight: 600; text-decoration: none; }

/* ---- Fase 26 ("Escala del Negocio"): grid compacto de 2 columnas para
   las tarjetas de sedes/profesionales -- mismo tratamiento visual de
   .tarjeta-industria (reuso deliberado: es el mismo patrón "elige una
   tarjeta"), solo con menos alto porque no necesitan un ícono grande. ---- */
.selector-escala { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e2); }
.selector-escala .tarjeta-industria { min-height: 68px; padding: var(--e3) var(--e2); }
.selector-escala .tarjeta-industria__nombre { font-size: var(--t-s); font-weight: 700; }
.selector-escala .tarjeta-industria__detalle { font-size: var(--t-xs); color: var(--texto-3); }

/* ==========================================================================
   FASE 21 (§2) — Registro Gamificado: wizard de pasos + pantalla de
   bienvenida animada. Reutiliza los tokens/clases de siempre (.campo,
   .tarjeta-industria, .paleta-swatch) -- lo nuevo es la navegación por
   pasos y los chips de metas. Fase 25 (§3) suma un 4º paso de
   perfilamiento (dolor) antes del de metas -- ver .registro-fondo /
   .registro-tarjeta más arriba para el tratamiento glassmorphism.
   ========================================================================== */
.registro-progreso { display: flex; align-items: center; gap: var(--e2); }
.registro-progreso__paso {
  display: flex; align-items: center; gap: var(--e2);
  font-size: var(--t-xs); font-weight: 700; color: var(--texto-3);
}
.registro-progreso__paso span {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--r-full);
  background: var(--superficie-alta); color: var(--texto-3);
  font-size: 12px; transition: background var(--transicion), color var(--transicion);
}
.registro-progreso__paso em { font-style: normal; white-space: nowrap; }
.registro-progreso__paso.activo { color: var(--texto); }
.registro-progreso__paso.activo span { background: var(--brand-color); color: var(--text-on-cta); }
.registro-progreso__paso.completo span { background: color-mix(in srgb, var(--brand-color) 30%, var(--superficie-alta)); color: var(--texto); }
.registro-progreso__linea { flex: 1; height: 2px; background: var(--borde); border-radius: var(--r-full); }
/* <400px (mobile-first, ADR-08): 4 pasos con nombre completo ya no caben
   junto al círculo numerado -- se oculta el texto y el número/color
   (activo/completo) sigue comunicando el avance por sí solo. */
@media (max-width: 399px) {
  .registro-progreso__paso em { display: none; }
}

.registro-paso { display: flex; flex-direction: column; gap: var(--e4); animation: registro-paso-entra 260ms cubic-bezier(.4, 0, .2, 1); }
@keyframes registro-paso-entra { from { opacity: 0; transform: translateX(8px); } to { opacity: 1; transform: translateX(0); } }
@media (prefers-reduced-motion: reduce) { .registro-paso { animation: none; } }
.registro-nav { display: flex; align-items: center; justify-content: space-between; gap: var(--e3); }
.registro-nav .boton-primario { flex: 1; }

/* ---- Chips de metas (Paso 3): selección múltiple libre, sin radio/checkbox visible. ---- */
.metas-grid { display: flex; flex-direction: column; gap: var(--e2); }
.meta-chip {
  display: flex; align-items: center; gap: var(--e3); min-height: var(--tap-min);
  background: var(--superficie); border: none; box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  padding: var(--e3) var(--e4); text-align: left; font-weight: 600; color: var(--texto-2);
  transition: background var(--transicion), color var(--transicion), box-shadow var(--transicion);
}
.meta-chip .icono { color: var(--texto-3); transition: color var(--transicion); }
.meta-chip.activo {
  color: var(--texto);
  box-shadow: 0 0 0 1.5px var(--brand-color), var(--sombra-ultra-suave);
  background: color-mix(in srgb, var(--brand-color) 8%, var(--superficie));
}
.meta-chip.activo .icono { color: var(--brand-color); }

/* ---- Pantalla de éxito: checkmark de trazo dibujándose en CSS puro. ---- */
.registro-exito {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--e3);
  background: var(--fondo); text-align: center; padding: var(--e5);
}
.registro-exito__check { width: 96px; height: 96px; }
.registro-exito__circulo {
  stroke: var(--exito); stroke-width: 4; stroke-linecap: round;
  stroke-dasharray: 283; stroke-dashoffset: 283;
}
.registro-exito__marca {
  stroke: var(--exito); stroke-width: 6; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 80; stroke-dashoffset: 80;
}
.registro-exito.activo .registro-exito__circulo { animation: registro-dibujar 600ms cubic-bezier(.4, 0, .2, 1) forwards; }
.registro-exito.activo .registro-exito__marca { animation: registro-dibujar 400ms cubic-bezier(.4, 0, .2, 1) 500ms forwards; }
@keyframes registro-dibujar { to { stroke-dashoffset: 0; } }
.registro-exito__titulo { font-size: var(--t-xl); font-weight: 800; opacity: 0; animation: registro-exito-texto 500ms ease 700ms forwards; }
.registro-exito__texto { color: var(--texto-2); opacity: 0; animation: registro-exito-texto 500ms ease 900ms forwards; }
@keyframes registro-exito-texto { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .registro-exito__circulo, .registro-exito__marca { animation: none; stroke-dashoffset: 0; }
  .registro-exito__titulo, .registro-exito__texto { animation: none; opacity: 1; }
}

/* ---- Páginas legales (Fase 15, §4: /terminos /privacidad /reembolsos) ----
   Prosa larga, así que priorizan lectura: ancho de línea corto (65ch),
   jerarquía tipográfica clara, mismos tokens del resto del sitio (nunca
   colores a mano). Comparten un solo bloque de CSS -- las 3 vistas son
   HTML casi idéntico, solo cambia el contenido. ---- */
.legal-shell { max-width: 720px; margin: 0 auto; min-height: 100vh; padding-bottom: var(--e7); }
.legal-header {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--e3) var(--e4);
  background: var(--superficie-alta);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  border-bottom: 1px solid var(--borde);
}
.legal-header__marca { font-weight: 800; font-size: var(--t-m); text-decoration: none; color: var(--texto); }
.legal-tabs { display: flex; gap: var(--e2); padding: var(--e4) var(--e4) 0; flex-wrap: wrap; }
.legal-tabs__item {
  padding: var(--e2) var(--e4); border-radius: var(--r-full);
  border: 1px solid var(--borde); background: var(--superficie);
  font-size: var(--t-s); font-weight: 600; color: var(--texto-2); text-decoration: none;
  transition: var(--transicion);
}
.legal-tabs__item.activo { border-color: var(--acento); color: var(--texto); background: var(--superficie-alta); }
.legal-contenido { padding: var(--e6) var(--e4); max-width: 65ch; margin: 0 auto; }
.legal-contenido h1 { font-size: var(--t-xl); font-weight: 800; letter-spacing: -.01em; margin-bottom: var(--e2); }
.legal-meta { font-size: var(--t-s); color: var(--texto-3); margin-bottom: var(--e6); }
.legal-contenido h2 { font-size: var(--t-l); font-weight: 700; margin: var(--e6) 0 var(--e3); letter-spacing: -.01em; }
.legal-contenido h3 { font-size: var(--t-m); font-weight: 700; margin: var(--e5) 0 var(--e2); }
.legal-contenido p { color: var(--texto-2); line-height: 1.7; margin-bottom: var(--e3); }
.legal-contenido ul, .legal-contenido ol { color: var(--texto-2); line-height: 1.7; margin: 0 0 var(--e3); padding-left: var(--e5); display: flex; flex-direction: column; gap: var(--e2); }
.legal-contenido li::marker { color: var(--texto-3); }
.legal-contenido strong { color: var(--texto); font-weight: 700; }
.legal-contenido a { color: var(--acento); font-weight: 600; }
.legal-aviso {
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-m);
  padding: var(--e4); margin: var(--e5) 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.6;
}
.legal-footer { text-align: center; padding: var(--e6) var(--e4); color: var(--texto-3); font-size: var(--t-s); }
.legal-footer a { color: var(--texto-2); font-weight: 600; }

/* ---- Fase 13 (§3, "Paletas B2B"): 5 paletas predefinidas (Minimalista,
   Elegante, Femenina, Neutra, Colorida), reutilizadas tal cual en el
   selector visual de /registro y en "Configuración del Negocio" del panel
   admin. Cada .paleta-swatch recibe su primario/secundario por variables
   inline (--sw-primario/--sw-secundario, ver registro.php y admin.js) para
   no duplicar los hex en dos lenguajes distintos. ---- */
.paletas-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--e3); }
.paleta-swatch {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  gap: var(--e2);
  height: 76px; padding: var(--e2);
  border-radius: var(--r-m); border: 2px solid var(--borde);
  background: linear-gradient(135deg, var(--sw-primario, var(--primario)), var(--sw-secundario, var(--acento)));
  transition: transform var(--transicion), border-color var(--transicion), box-shadow var(--transicion);
}
.paleta-swatch:active { transform: scale(.96); }
.paleta-swatch.activo {
  border-color: var(--sw-secundario, var(--acento));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sw-secundario, var(--acento)) 35%, transparent);
}
.paleta-swatch__nombre {
  font-size: 11px; font-weight: 700; color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  background: rgba(0, 0, 0, .28); border-radius: var(--r-full); padding: 2px var(--e2);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
/* §Motor de Temas Inteligente: mismo tratamiento circular de .hex-campo__preview
   (Settings > Negocio > Personalización de marca) para que el picker de color
   nunca se vea "feo" sin importar en qué pantalla del panel aparezca -- los
   dos escriben las mismas columnas color_primario/color_secundario. */
.paleta-colores-manuales { display: flex; gap: var(--e4); }
.paleta-colores-manuales input[type="color"] {
  width: 44px; height: 44px; padding: 0; margin: 0;
  border: 2px solid var(--borde); border-radius: 50%; background: none; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  box-shadow: var(--sombra-ultra-suave);
  transition: transform .3s ease, box-shadow .3s ease;
}
.paleta-colores-manuales input[type="color"]:hover { transform: scale(1.06); }
.paleta-colores-manuales input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; }
.paleta-colores-manuales input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50%; }
.paleta-colores-manuales input[type="color"]::-moz-color-swatch { border: none; border-radius: 50%; }

/* ---- §Refactor UI/UX Premium (Fase 2, "Motor de Temas Inteligente"):
   grid de 12 paletas de lujo + campos HEX con previsualización circular,
   dentro de Settings > Negocio. Estética Apple/Stripe -- bordes suaves,
   sombras difuminadas, transición en todo cambio de color. Reemplaza los
   3 <input type="color"> desnudos de la versión anterior (el selector de
   paletas predefinidas de /registro, .paleta-swatch, sigue vivo aparte). ---- */
.motor-temas__seccion-titulo {
  font-size: var(--t-etiqueta); font-weight: 600; color: var(--texto-2); opacity: .8;
  text-transform: uppercase; letter-spacing: .04em; margin: 0 0 var(--e3);
}
.motor-temas__seccion-titulo:not(:first-child) { margin-top: var(--e5); }
.motor-temas__grupo { display: flex; flex-direction: column; gap: var(--e4); }

.paletas-lujo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: var(--e3); }
.paleta-lujo {
  display: flex; flex-direction: column; align-items: center; gap: var(--e2);
  padding: var(--e3) var(--e2); border-radius: var(--r-m); border: 1.5px solid transparent;
  background: var(--superficie-alta); box-shadow: var(--sombra-ultra-suave);
  transition: border-color .3s ease, transform .3s ease, box-shadow .3s ease;
}
.paleta-lujo:hover { transform: translateY(-2px); }
.paleta-lujo:active { transform: translateY(0) scale(.97); }
.paleta-lujo.seleccionada { border-color: var(--brand-color); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-color) 22%, transparent); }
.paleta-lujo__muestra {
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid color-mix(in srgb, var(--texto) 10%, transparent);
  background: conic-gradient(var(--paleta-primario) 0deg 120deg, var(--paleta-secundario) 120deg 240deg, var(--paleta-fondo) 240deg 360deg);
  transition: transform .3s ease;
}
.paleta-lujo:hover .paleta-lujo__muestra { transform: scale(1.06); }
.paleta-lujo__nombre { font-size: 11px; font-weight: 600; color: var(--texto-2); text-align: center; line-height: 1.25; }
.paleta-lujo.seleccionada .paleta-lujo__nombre { color: var(--texto); }

/* Campo HEX premium: el propio <input type="color"> nativo, despojado de su
   cuadrito con flechita por defecto y reestilado como una previsualización
   circular limpia (::-webkit-color-swatch) -- sigue abriendo el selector
   nativo del sistema al tocarlo, pero ya no se ve "feo". */
.hex-campo { display: flex; align-items: center; gap: var(--e3); }
.hex-campo__preview {
  flex-shrink: 0; width: 44px; height: 44px; padding: 0; margin: 0;
  border: 2px solid var(--borde); border-radius: 50%; background: none; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  box-shadow: var(--sombra-ultra-suave);
  transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.hex-campo__preview:hover { transform: scale(1.06); }
.hex-campo__preview:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-color) 35%, transparent); }
.hex-campo__preview::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50%; }
.hex-campo__preview::-webkit-color-swatch { border: none; border-radius: 50%; }
.hex-campo__preview::-moz-color-swatch { border: none; border-radius: 50%; }
.hex-campo__input {
  flex: 1; min-width: 0; height: 44px; padding: 0 var(--e3);
  border-radius: var(--r-s); border: 1px solid var(--borde); background: var(--superficie);
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: var(--t-s); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--texto);
  transition: border-color .3s ease, box-shadow .3s ease;
}
.hex-campo__input:focus { outline: none; border-color: var(--brand-color); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-color) 20%, transparent); }
.hex-campo__input.invalido { border-color: var(--peligro); box-shadow: 0 0 0 3px color-mix(in srgb, var(--peligro) 16%, transparent); }

/* Mini tarjeta "así se ve tu marca": demuestra en vivo, dentro del propio
   panel de Settings, que el Motor de Contraste Automático nunca deja texto
   ilegible -- fondo y botón se pintan con los colores elegidos, pero el
   color del TEXTO lo decide siempre textoLegibleSobre() (admin.js). */
.motor-temas__vista-previa {
  margin-top: var(--e5); padding: var(--e5); border-radius: var(--r-l);
  border: 1px solid var(--borde); display: flex; flex-direction: column; align-items: center; gap: var(--e4);
  transition: background-color .3s ease, color .3s ease;
}
.motor-temas__vista-previa-texto { font-weight: 600; font-size: var(--t-s); opacity: .85; }
.motor-temas__vista-previa-boton {
  min-height: var(--tap-min); padding: 0 var(--e5); border: none; border-radius: var(--r-m);
  font-weight: 700; font-size: var(--t-s); cursor: default;
  transition: background-color .3s ease, color .3s ease;
}
.motor-temas__contraste {
  margin: var(--e2) 0 0; display: flex; align-items: center; gap: var(--e2);
  font-size: var(--t-xs); color: var(--texto-2);
}
.motor-temas__contraste-punto { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; transition: background-color .3s ease; }
.motor-temas__contraste-punto.ok { background: var(--exito); }
.motor-temas__contraste-punto.bajo { background: var(--alerta); }

/* Slider de opacidad de Glassmorphism: track/thumb custom para que se vea
   consistente entre navegadores (los nativos varían mucho de estilo). */
.rango-vidrio { display: flex; align-items: center; gap: var(--e3); min-height: var(--tap-min); }
.rango-vidrio input[type="range"] {
  flex: 1; -webkit-appearance: none; appearance: none; height: 6px; border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--borde), var(--brand-color));
  outline: none;
}
.rango-vidrio input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--brand-color); border: 3px solid var(--fondo); box-shadow: var(--sombra-suave); cursor: pointer;
}
.rango-vidrio input[type="range"]::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--fondo);
  background: var(--brand-color); box-shadow: var(--sombra-suave); cursor: pointer;
}
.rango-vidrio__valor { flex-shrink: 0; min-width: 40px; text-align: right; font-weight: 700; font-size: var(--t-s); font-variant-numeric: tabular-nums; }

/* ---- Estructura de la app autenticada ---- */
.admin-panel { min-height: 100vh; display: flex; flex-direction: column; }
/* El banner de trial y el encabezado comparten un mismo sticky (§3, Fase 15):
   si cada uno tuviera su propio position:sticky;top:0 competirían por el
   mismo offset y el encabezado taparía el banner. Envolviéndolos juntos,
   el conjunto se pega como una sola pieza y el banner simplemente empuja
   al encabezado hacia abajo cuando está visible. */
.admin-topbar { position: sticky; top: 0; z-index: 20; }
.admin-encabezado {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--e3) var(--e4);
  background: var(--superficie-alta);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  border-bottom: 1px solid var(--borde);
  font-weight: 700; font-size: var(--t-l);
}
/* ---- Navegación líquida (Fase 16, §1): un solo botón de "volver" global,
   en vez de que cada pantalla de "Más" reinvente el suyo (había 6 copias
   casi idénticas de .boton-volver repetidas en admin.js). admin.js lo
   muestra/oculta según la pila de vistas (estado.pilaVistas) y lo conecta
   a history.back(), así que el gesto/botón nativo de "atrás" del
   navegador o del celular también funciona -- cero callejones sin
   salida. ---- */
.admin-encabezado__izq, .admin-encabezado__der { display: flex; align-items: center; gap: var(--e2); }
#admin-boton-volver { font-size: var(--t-l); line-height: 1; }

/* ---- Banner de retención de trial (§3, Fase 15) ----
   Oculto por defecto (hidden en el HTML); admin.js lo muestra solo cuando
   estado_suscripcion === 'trial', con los días restantes calculados en
   SuscripcionService. A partir de 3 días o menos pasa a "es-urgente":
   fondo rojo + el CTA respira (mismo lenguaje de "urgencia" que el glow
   del CTA de la landing, aquí en tono de alerta en vez de venta). ---- */
.admin-banner-trial {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
  padding: var(--e2) var(--e4);
  background: color-mix(in srgb, var(--alerta) 16%, var(--fondo));
  border-bottom: 1px solid color-mix(in srgb, var(--alerta) 35%, transparent);
  font-size: var(--t-s); font-weight: 600; color: var(--texto);
  transition: background var(--transicion), border-color var(--transicion);
}
.admin-banner-trial__cta {
  flex-shrink: 0;
  background: var(--alerta); color: #1F1300;
  font-size: 12px; font-weight: 800; white-space: nowrap;
  padding: 6px 14px; border-radius: var(--r-full);
}
.admin-banner-trial.es-urgente {
  background: color-mix(in srgb, var(--peligro) 18%, var(--fondo));
  border-bottom-color: color-mix(in srgb, var(--peligro) 45%, transparent);
}
.admin-banner-trial.es-urgente .admin-banner-trial__cta {
  background: var(--peligro); color: #fff;
  animation: admin-banner-respirar 1.8s ease-in-out infinite;
}
@keyframes admin-banner-respirar {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--peligro) 55%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--peligro) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .admin-banner-trial.es-urgente .admin-banner-trial__cta { animation: none; }
}

/* ---- Fase 23 ("Entrar como Cliente"): banner de modo soporte -- mismo
   layout de .admin-banner-trial (comparten el sticky de .admin-topbar),
   tono violeta para no confundirse con la urgencia ámbar/roja del trial:
   esto no es una alerta para el dueño del negocio, es una nota de que un
   humano de soporte está viendo su panel para ayudarlo. ---- */
.admin-banner-soporte {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
  padding: var(--e2) var(--e4);
  background: color-mix(in srgb, #7C3AED 18%, var(--fondo));
  border-bottom: 1px solid color-mix(in srgb, #7C3AED 40%, transparent);
  font-size: var(--t-s); font-weight: 600; color: var(--texto);
}
.admin-banner-soporte__salir {
  flex-shrink: 0; background: #7C3AED; color: #fff;
  font-size: 12px; font-weight: 800; white-space: nowrap;
  padding: 6px 14px; border-radius: var(--r-full);
}
.admin-contenido {
  flex: 1; padding: var(--e5) var(--e4) calc(80px + var(--seguro-abajo));
  display: flex; flex-direction: column; gap: var(--e4);
}

/* ---- Navegación inferior fija (§7.2: 5 íconos) ---- */
.admin-nav-inferior {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  max-width: 720px; margin: 0 auto;
  display: flex;
  background: var(--superficie-alta);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  border-top: 1px solid var(--borde);
  padding-bottom: var(--seguro-abajo);
}
/* Fase 21 (§1): iOS-clean -- gris inactivo, color de marca activo, SIN
   glow/resplandor. El único indicador de estado es una píldora de fondo
   planísima detrás del icono (idéntica al "pill" de iOS 15+), nunca una
   sombra de color ni un brillo. */
.admin-nav__item {
  flex: 1; min-height: 56px; background: none; border: none; color: var(--texto-3);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  font-size: 11px; font-weight: 600;
  transition: color var(--transicion);
}
.admin-nav__item .icono-pildora {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 24px; border-radius: var(--r-full);
  transition: background var(--transicion);
}
.admin-nav__item.activo { color: var(--brand-color); }
.admin-nav__item.activo .icono-pildora { background: color-mix(in srgb, var(--brand-color) 14%, transparent); }
.admin-nav__item[disabled] { opacity: .35; }

/* ---- KPIs de "Hoy" (§Refactor UI/UX Premium, "Sistema de Tarjetas"):
   Glassmorphism unificado -- fondo translúcido + backdrop-filter (el mismo
   --desenfoque de sheets/topbar, antes exclusivo de superficies flotantes,
   ahora también en las tarjetas de datos) y más padding para que respiren.
   Jerarquía: etiqueta sutil arriba (uppercase, --texto-2), la métrica es
   SIEMPRE el elemento más grande/pesado de la tarjeta (ver el orden del
   markup en admin.js: etiqueta antes que valor). ---- */
/* ---- Tarjetas de métrica "Ultra-Compactas" (§Compact Dashboard, Alpha
   Theme): grid de 2 columnas fijo -- también en móvil -- para que las 4
   tarjetas de KPI ocupen la mitad del alto vertical de antes. Tipografía
   deliberadamente contenida (dato nunca > 1.5rem, weight 600 en vez de
   800/black) para que el conjunto se lea como una fila de datos densa y
   elegante, no como 4 titulares gritando por turnos. */
.kpis-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e2); }
.kpi-tarjeta {
  background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e4); display: flex; flex-direction: column; gap: 4px;
}
.kpi-tarjeta__etiqueta {
  font-size: .75rem; font-weight: 500; color: var(--texto-2); opacity: .6;
  text-transform: uppercase; letter-spacing: .05em;
}
.kpi-tarjeta__valor {
  font-size: 1.5rem; font-weight: 600; line-height: 1.15;
  overflow-wrap: break-word; word-break: break-word;
}

.banda-urgente {
  background: var(--alerta); color: var(--primario); font-weight: 700;
  border-radius: var(--r-l); padding: var(--e3) var(--e4); font-size: var(--t-s);
  display: flex; align-items: center; gap: var(--e2);
}

/* ---- Bandeja de acciones (§7.3, "el motor de WhatsApp") ---- */
.bandeja-lista { display: flex; flex-direction: column; gap: var(--e3); }
.bandeja-tarjeta {
  background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e5) var(--e4); display: flex; flex-direction: column; gap: var(--e2);
}
.bandeja-tarjeta__cabecera { display: flex; align-items: center; gap: var(--e2); }
.bandeja-tarjeta__icono { display: flex; color: var(--texto-2); }
.bandeja-tarjeta__icono .icono { width: 20px; height: 20px; }
.bandeja-tarjeta__nombre { font-weight: 700; }
.bandeja-tarjeta__mensaje {
  width: 100%; resize: vertical; min-height: 72px; padding: var(--e2);
  border: 1px solid var(--borde); border-radius: var(--r-s); background: var(--superficie-alta);
  font-size: var(--t-s); line-height: 1.4;
}
.bandeja-tarjeta__acciones { display: flex; gap: var(--e2); }
.bandeja-tarjeta__acciones .boton { flex: 1; }
.bandeja-tarjeta--enviado { opacity: .7; }

/* ---- Línea de tiempo del día ---- */
.linea-tiempo { display: flex; flex-direction: column; gap: var(--e2); }
.cita-fila {
  display: flex; align-items: center; gap: var(--e3);
  background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e5); border-left: 4px solid rgb(var(--servicio-rgb, var(--acento-rgb)));
  text-align: left;
}
.cita-fila__hora { font-weight: 700; font-size: var(--t-s); min-width: 52px; align-self: flex-start; }
.cita-fila__info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* Cadenas largas de cliente/servicio nunca se recortan con "…" (Refactor UI/UX
   Premium §1): se rompen a una segunda línea en vez de perder información. */
.cita-fila__cliente { font-weight: 600; overflow-wrap: break-word; word-break: break-word; }
.cita-fila__servicio { font-size: var(--t-etiqueta); font-weight: 400; color: var(--texto-2); opacity: .7; overflow-wrap: break-word; word-break: break-word; }
.insignia-estado {
  font-size: 10px; font-weight: 700; padding: 2px var(--e2); border-radius: var(--r-full);
  background: var(--superficie-alta); color: var(--texto-2); white-space: nowrap;
}
.insignia-estado.confirmada { background: color-mix(in srgb, var(--exito) 25%, transparent); color: var(--exito); }
.insignia-estado.pendiente_abono, .insignia-estado.pendiente_aprobacion, .insignia-estado.retenida { background: color-mix(in srgb, var(--alerta) 25%, transparent); color: var(--alerta); }
.insignia-estado.completada { background: color-mix(in srgb, var(--texto-3) 25%, transparent); color: var(--texto-2); text-decoration: line-through; }
.insignia-estado.no_show, .insignia-estado.cancelada_admin, .insignia-estado.cancelada_cliente { background: color-mix(in srgb, var(--peligro) 25%, transparent); color: var(--peligro); }

/* ---- Fase 12: resumen BI + gráfica (pantalla "Hoy") ----
   §Compact Dashboard: 2 columnas fijas en móvil (mismo criterio que
   .kpis-grid) -- auto-fit solo se habilita desde 640px, donde ya sobra
   ancho para que las 3 tarjetas respiren libres sin forzar una fila
   desigual de 2+1. */
.resumen-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e2); }
@media (min-width: 640px) {
  .resumen-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
.resumen-tarjeta {
  position: relative; overflow: hidden;
  background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e4); display: flex; flex-direction: column; gap: 4px;
}
.resumen-tarjeta::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--acento), var(--morado));
}
.resumen-tarjeta__etiqueta {
  font-size: .75rem; font-weight: 500; color: var(--texto-2); opacity: .6;
  text-transform: uppercase; letter-spacing: .05em;
}
/* Nunca se corta con "…" (ej. "Nombre del Especialista (Master)" como Top
   Recurso): rompe a varias líneas en vez de perder el dato. */
.resumen-tarjeta__valor { font-size: 1.5rem; font-weight: 600; line-height: 1.2; overflow-wrap: break-word; word-break: break-word; }
.resumen-tarjeta__sub { font-size: .75rem; font-weight: 400; color: var(--texto-2); opacity: .6; }

.grafica-tarjeta {
  background: var(--superficie); border: 1px solid var(--borde); box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e5);
}
.grafica-tarjeta__titulo { font-size: var(--t-s); font-weight: 700; margin-bottom: var(--e3); }
.grafica-tarjeta__lienzo { position: relative; height: 180px; width: 100%; }

/* ---- Botón flotante "+" ---- */
.boton-flotante {
  position: fixed; right: var(--e4); bottom: calc(80px + var(--seguro-abajo)); z-index: 25;
  width: 56px; height: 56px; border-radius: var(--r-full);
  background: var(--acento); color: var(--text-on-cta); font-size: 28px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; border: none;
  box-shadow: var(--sombra);
  max-width: none;
}

/* ---- Bottom sheet (§7.0: toda acción termina aquí, nunca en pantalla nueva) ---- */
.admin-sheet-fondo {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(0, 0, 0, .5);
}
.admin-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  max-width: 720px; margin: 0 auto;
  max-height: 85vh; overflow-y: auto;
  background: color-mix(in srgb, var(--bg-dark) 86%, transparent);
  -webkit-backdrop-filter: var(--desenfoque-fuerte);
  backdrop-filter: var(--desenfoque-fuerte);
  border: 1px solid var(--borde); border-bottom: none;
  border-top: 3px solid color-mix(in srgb, var(--brand-color) 70%, var(--borde));
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: var(--e4) var(--e5) calc(var(--e6) + var(--seguro-abajo));
  box-shadow: var(--sombra-flotante);
  animation: subir-hoja 220ms cubic-bezier(.4, 0, .2, 1);
}
@keyframes subir-hoja { from { transform: translateY(100%); } to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .admin-sheet { animation: none; } }
.admin-sheet__agarre {
  width: 40px; height: 4px; border-radius: var(--r-full);
  background: color-mix(in srgb, var(--brand-color) 35%, var(--borde));
  margin: 0 auto var(--e4);
}
.admin-sheet__titulo {
  font-size: var(--t-xl); font-weight: 800; margin-bottom: var(--e4);
  color: var(--texto); letter-spacing: -.01em;
}
.admin-sheet__titulo--con-icono { display: flex; align-items: center; gap: var(--e2); color: var(--alerta); }
.admin-sheet__subtitulo { font-size: var(--t-s); color: var(--texto-2); margin: calc(var(--e4) * -1) 0 var(--e4); }
.admin-sheet__accion {
  width: 100%; min-height: 56px; display: flex; align-items: center; gap: var(--e3);
  background: none; border: none; border-radius: var(--r-m);
  font-size: var(--t-m); font-weight: 600; text-align: left; color: var(--texto);
  padding: 0 var(--e2); margin: 0 calc(var(--e2) * -1);
  transition: background var(--transicion);
}
.admin-sheet__accion + .admin-sheet__accion { margin-top: 2px; }
.admin-sheet__accion:active { background: var(--superficie-alta); }
.admin-sheet__accion.peligro { color: var(--peligro); }

/* ---- Agenda (§Rediseño Timeline Continua): línea de tiempo continua,
   estilo Google/Apple Calendar, mobile-first (ADR: mobile-first literal).
   Eje Y de horas a la izquierda + lienzo continuo a la derecha donde las
   citas flotan en su posición exacta al minuto -- nada de "slots" de
   intervalo fijo. Una sola cuadrícula sirve para ambos tamaños: en móvil
   solo la columna del recurso activo es visible (.agenda-columna--activa,
   elegida con los chips de abajo); desde 768px se ven todas lado a lado. ---- */
.agenda-selector-fecha { display: flex; align-items: center; justify-content: space-between; gap: var(--e3); }

/* -- Selector de recurso: chips horizontales, solo aporta con 2+ recursos -- */
.agenda-chips-recursos {
  display: flex; gap: var(--e2); overflow-x: auto; padding-bottom: 2px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.agenda-chips-recursos:empty { display: none; }
.agenda-chips-recursos::-webkit-scrollbar { display: none; }
.agenda-chip-recurso {
  flex-shrink: 0; padding: var(--e2) var(--e4); border-radius: var(--r-full);
  border: 1px solid var(--borde); background: var(--superficie);
  font-size: var(--t-s); font-weight: 600; color: var(--texto-2);
  transition: background var(--transicion), border-color var(--transicion), color var(--transicion);
}
.agenda-chip-recurso.seleccionada {
  border-color: var(--acento); color: var(--texto);
  background: color-mix(in srgb, var(--acento) 14%, var(--superficie));
}

@media (min-width: 768px) {
  /* En escritorio todas las columnas se ven siempre lado a lado: el
     selector de chips no aporta nada y se oculta. */
  .agenda-chips-recursos { display: none; }
}

/* ---- Fix "scroll fluido y primeras horas visibles" ----
   Antes el lienzo crecía con toda la página (sin overflow propio) y el
   scroll real ocurría en el body: .agenda-horas__encabezado y
   .agenda-columna__encabezado (position:sticky;top:0, z-index 2) competían
   por el mismo top:0 que .admin-topbar (también sticky;top:0, pero
   z-index 20), así que el header fijo del panel siempre ganaba y tapaba
   las primeras horas del día detrás suyo. Dándole a .agenda-grid su
   propio overflow:auto se vuelve su propio contexto de scroll: sus sticky
   internos ya solo compiten entre sí, nunca con el header de fuera, y el
   gesto de scroll queda contenido en el lienzo -- no arrastra consigo el
   header ni la nav inferior. padding-block da aire antes de la primera
   hora y después de la última, para que ni quede pegada al borde ni el
   FAB (fixed, bottom:80px) la tape al llegar al final. ---- */
.agenda-grid {
  /* Fase 26: fuente única de verdad para la altura de AMBOS headers
     sticky (horas + cada columna de especialista) y el aire reservado
     antes de la primera hora -- ver comentario en .agenda-horas__cuerpo. */
  --agenda-header-h: 37px;
  --agenda-primera-hora-aire: var(--e3);
  display: flex;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  scroll-behavior: smooth;
  background: var(--agenda-celda); border-radius: var(--r-l);
  border: none;
  box-shadow: var(--sombra-ultra-suave);
  height: min(70vh, 640px);
  height: min(70dvh, 640px);
  padding-block: var(--e3);
  scrollbar-width: thin;
  scrollbar-color: var(--agenda-linea-fuerte) transparent;
}
.agenda-grid::-webkit-scrollbar { width: 6px; height: 6px; }
.agenda-grid::-webkit-scrollbar-track { background: transparent; }
.agenda-grid::-webkit-scrollbar-thumb { background: var(--agenda-linea-fuerte); border-radius: var(--r-full); }
@media (prefers-reduced-motion: reduce) { .agenda-grid { scroll-behavior: auto; } }

/* Columna fija de horas (eje Y): sticky dentro del scroll horizontal para
   que las etiquetas nunca se pierdan de vista, sin duplicar el scroll
   vertical (la cuadrícula entera crece con la página, como antes). */
.agenda-horas {
  position: sticky; left: 0; z-index: 8; flex: 0 0 52px;
  background: var(--agenda-celda);
  border-right: 1px solid var(--agenda-linea-fuerte);
}
.agenda-horas__encabezado {
  position: sticky; top: 0; z-index: 15;
  background: var(--agenda-celda); height: var(--agenda-header-h);
  border-bottom: 1px solid var(--agenda-linea-fuerte);
}
/* Fix DEFINITIVO "primera hora tapada por el header" (auditoría §Fase 4):
   la Fase 26 intentó resolver esto con padding-top, y NO funcionaba -- la
   razón es una trampa clásica del modelo de caja: .agenda-horas__cuerpo
   solo contiene hijos position:absolute (las .agenda-hora-etiqueta), y
   para un hijo absolutamente posicionado, `top` se mide desde el PADDING
   EDGE del contenedor -- el borde que ya queda pegado al `border`, sin
   moverse un píxel aunque cambies el padding-top. El padding-top solo
   empuja el CONTENIDO en flujo normal (texto, hijos estáticos); un hijo
   `position:absolute` con `top:0` lo ignora por completo. Por eso la
   primera hora seguía naciendo exactamente en el borde superior del
   lienzo, debajo del header sticky, sin importar cuánto padding-top se le
   pusiera.
   La solución real: `margin-top`. El margin SÍ desplaza la caja completa
   de .agenda-horas__cuerpo dentro del flujo normal (empujándola lejos del
   header, que es su hermano anterior) -- y como esta caja es el propio
   "containing block" de sus hijos absolutos, al moverse ella se mueve con
   ella el origen `top:0` de todos sus hijos. Resultado: la primera hora
   nace EXACTAMENTE --agenda-primera-hora-aire píxeles debajo del header,
   nunca detrás. */
.agenda-horas__cuerpo { position: relative; margin-top: var(--agenda-primera-hora-aire); }
/* Minimalista a propósito: "8 AM", nunca "08:00 AM" — el eje es una
   referencia rápida, no un reloj. Una sola línea, alineada a la derecha,
   gris muy sutil, para no competir visualmente con las citas. */
.agenda-hora-etiqueta {
  position: absolute; right: var(--e2); transform: translateY(-50%);
  font-size: 11px; font-weight: 500; color: var(--texto-3);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Móvil: solo la columna del recurso activo, a ancho completo (nunca
   scroll horizontal); escritorio: todas lado a lado, como siempre. */
.agenda-columna { display: none; background: var(--agenda-celda); position: relative; }
.agenda-columna.agenda-columna--activa { display: block; flex: 1 1 100%; min-width: 0; }
@media (min-width: 768px) {
  .agenda-columna { display: block; flex: 1; min-width: 148px; }
  .agenda-columna + .agenda-columna { border-left: 1px solid var(--agenda-linea); }
}
/* Bugfix "header de especialista se solapa con la cuadrícula al hacer
   scroll" (auditoría §Fase 26): altura fija igual a --agenda-header-h (la
   misma que .agenda-horas__encabezado, para que ambos headers sticky
   queden perfectamente a la misma línea al desplazarse), z-index muy por
   encima de TODO lo que vive dentro del lienzo (franjas, citas, bloqueos
   -- todas con z-index:auto) y también por encima de .agenda-horas
   (z-index:8, la columna de horas), fondo 100% opaco (nunca transparente,
   nunca color-mix con alpha) y una sombra hacia abajo que refuerza la
   sensación de "flota sobre" cuando las citas se deslizan debajo. */
.agenda-columna__encabezado {
  position: sticky; top: 0; z-index: 15; height: var(--agenda-header-h); box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  background: var(--agenda-celda-alt); padding: 0 var(--e2); text-align: center;
  font-weight: 700; font-size: var(--t-s); border-bottom: 1px solid var(--agenda-linea-fuerte);
  /* Mismo truco de --agenda-linea (color-mix sobre --texto): una sombra
     "negra" fija se ve correcta en modo claro pero se nota sucia/gris sobre
     el lienzo ya oscuro de modo oscuro -- color-mix se adapta sola a los
     dos temas sin duplicar la regla. */
  box-shadow: 0 2px 6px color-mix(in srgb, var(--texto) 8%, transparent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* margin-top (no padding-top: ver la explicación larga en
   .agenda-horas__cuerpo) -- mismo valor que la columna de horas, para que
   la primera franja/cita de CADA especialista nazca debajo de su título,
   nunca detrás, y siga alineada en píxeles con el eje de horas. */
.agenda-columna__cuerpo { position: relative; cursor: pointer; margin-top: var(--agenda-primera-hora-aire); }

/* ---- Franjas horarias: apenas una insinuación de línea cada 30 min (algo
   más marcada en punto). "Lienzo limpio", no cuadrícula de hoja de
   cálculo: la separación la da el espacio, no el trazo. ---- */
.agenda-franja {
  position: absolute; left: 0; right: 0;
  border-bottom: 1px solid var(--agenda-linea);
  pointer-events: none;
}
.agenda-franja--par { background: var(--agenda-celda-alt); }
.agenda-franja--hora { border-bottom-color: var(--agenda-linea-fuerte); }

/* ---- Tarjetas de cita "Glassmorphism sustancial" (§Refactor UI/UX Premium,
   Fase 3): reemplaza el bloque plano de color sólido por una tarjeta de
   verdad -- cristal esmerilado teñido con el color del servicio, cabecera
   con la hora anclada a la izquierda + tag de estado (reutiliza
   .insignia-estado, mismo lenguaje visual que la línea de tiempo de "Hoy")
   y el nombre del servicio con un ícono ligero. left/width se calculan en
   JS por cita (asignarCarriles: §Bugfix "bloques apilados") — dos citas
   simultáneas del mismo recurso se reparten el ancho en vez de dibujarse
   una encima de la otra, nunca con texto ilegible superpuesto. ---- */
/* §Alpha-Channel Theme Engine: el fondo de la tarjeta de cita NUNCA es un
   color-mix "horneado" contra --agenda-celda -- eso pre-calcula un tono
   fijo que solo coincide con el lienzo cuando cae exactamente sobre una
   celda par (--agenda-celda-alt es otro valor) y que en modo oscuro
   termina "sucio" porque mezcla, no compone. rgba(var(--servicio-rgb), α)
   es transparencia real: compone sobre lo que sea que haya detrás --franja
   par o impar, blur incluido-- así que el mismo bloque luce correcto sin
   importar el tema o la fila donde caiga. Mismo criterio para el borde y
   el texto del cliente: color sólido/RGB puro, nunca mezclado. */
.agenda-cita {
  position: absolute; border: none;
  background: rgba(var(--servicio-rgb, var(--acento-rgb)), .12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-left: 3px solid rgb(var(--servicio-rgb, var(--acento-rgb)));
  border-radius: var(--r-m); padding: 6px 9px; font-size: 11px; overflow: hidden;
  box-shadow: var(--sombra-ultra-suave);
  transition: transform var(--transicion), box-shadow var(--transicion), background var(--transicion);
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start; text-align: left;
}
.agenda-cita:active { transform: scale(.97); }
/* Auditoría §Fase 25: en escritorio (mouse) las citas no daban ninguna
   señal de ser interactivas hasta el click -- z-index:1 en hover para que
   la sombra no quede recortada por la cita vecina (carriles apilados, ver
   comentario de arriba), sin desplazar el layout de las demás. */
@media (hover: hover) {
  .agenda-cita:hover {
    background: rgba(var(--servicio-rgb, var(--acento-rgb)), .20);
    box-shadow: 0 4px 14px rgba(var(--servicio-rgb, var(--acento-rgb)), .30);
    z-index: 2;
  }
}
.agenda-cita__cabecera { display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%; }
.agenda-cita__hora { font-weight: 800; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--texto); flex-shrink: 0; }
.agenda-cita .insignia-estado { font-size: 9px; padding: 1px 6px; flex-shrink: 0; }
.agenda-cita__cliente, .agenda-cita__servicio {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
/* Texto principal teñido con el color real del servicio (rgb puro, no
   mezclado) para el look "tag" de Linear/Apple Calendar -- pero solo
   cuando admin.js confirmó matemáticamente (ratio WCAG contra el lienzo)
   que ese tono tiene contraste suficiente; si no, cae a .agenda-cita--texto-neutro
   y usa el texto del tema, que siempre es legible por diseño. */
.agenda-cita__cliente { font-size: 12px; font-weight: 700; color: rgb(var(--servicio-rgb, var(--acento-rgb))); }
.agenda-cita--texto-neutro .agenda-cita__cliente { color: var(--texto); }
.agenda-cita__servicio { display: flex; align-items: center; gap: 4px; opacity: .82; font-size: 10px; }
.agenda-cita__servicio .icono { flex-shrink: 0; width: 11px; height: 11px; }

/* Compacta (§Fase 3): citas muy cortas o con 3+ carriles simultáneos --
   colapsa a una sola fila (hora + cliente), oculta el tag de estado y el
   servicio en vez de amontonarlos en un espacio que no alcanza. */
.agenda-cita--compacta { flex-direction: row; align-items: center; gap: 6px; padding: 3px 8px; }
.agenda-cita--compacta .agenda-cita__cabecera { width: auto; flex-shrink: 0; }
.agenda-cita--compacta .agenda-cita__hora { font-size: 10px; }
.agenda-cita--compacta .agenda-cita__cliente { flex: 1; min-width: 0; font-size: 11px; }
.agenda-cita--compacta .insignia-estado, .agenda-cita--compacta .agenda-cita__servicio { display: none; }

/* ---- Indicador de hora actual (§Refactor UI/UX Premium, Fase 3): línea
   roja sutil + punto en el gutter, recalculada cada minuto por
   iniciarIndicadorHoraActual() (admin.js). pointer-events:none para que
   nunca robe el click de una cita o un espacio libre debajo suyo. ---- */
.agenda-indicador-ahora { position: absolute; pointer-events: none; z-index: 6; }
.agenda-indicador-ahora--linea {
  left: 0; right: 0; height: 2px; background: var(--peligro);
  transform: translateY(-50%); opacity: .85; border-radius: var(--r-full);
}
.agenda-indicador-ahora--punto {
  right: 1px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--peligro); transform: translate(50%, -50%);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--peligro) 22%, transparent);
}

/* Bloqueada (escritorio): misma textura a rayas que en la lista móvil --
   "el sistema no permite agendar aquí" se lee de un vistazo. */
.agenda-bloqueo {
  position: absolute; left: 3px; right: 8px; border: none;
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--peligro) 7%, transparent) 0 6px,
    color-mix(in srgb, var(--peligro) 14%, transparent) 6px 12px
  );
  border-left: 3px solid var(--peligro);
  border-radius: 6px; padding: 4px 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: flex-start;
  text-align: left;
}
.agenda-bloqueo strong { font-size: 11px; font-weight: 600; color: var(--peligro); }

/* ---- Banner-guía de la Agenda: reemplaza el aviso técnico por una
   tarjeta de bienvenida que explica el "radar del día" en un vistazo. ---- */
.agenda-guia {
  display: flex; align-items: center; gap: var(--e3);
  background: color-mix(in srgb, var(--brand-color) 10%, var(--superficie));
  border: 1px solid color-mix(in srgb, var(--brand-color) 24%, var(--borde));
  border-radius: var(--r-l); padding: var(--e3) var(--e4);
}
.agenda-guia__icono {
  width: 40px; height: 40px; border-radius: var(--r-full); flex-shrink: 0;
  background: color-mix(in srgb, var(--brand-color) 20%, var(--superficie-alta));
  display: flex; align-items: center; justify-content: center; font-size: 18px;
}
.agenda-guia__texto strong { display: block; font-size: var(--t-s); font-weight: 700; color: var(--texto); }
.agenda-guia__texto p { font-size: var(--t-xs); color: var(--texto-2); margin-top: 2px; }

/* ---- Comprobante de pago (§9.3) ---- */
.comprobante-visor { display: flex; justify-content: center; }
.comprobante-imagen {
  width: 100%; max-height: 50vh; object-fit: contain;
  border-radius: var(--r-m); border: 1px solid var(--borde); background: var(--superficie);
}
.comprobante-montos { margin-top: var(--e3); }
.comprobante-monto-alerta .resumen-fila__valor { color: var(--peligro); }

/* ---- Subida de comprobante en el embudo público (§6.9, §9.2) ---- */
.subir-comprobante { display: flex; flex-direction: column; align-items: center; gap: var(--e2); margin-top: var(--e3); }
.subir-comprobante label { text-align: center; }

/* ---- Configuración: listas y formularios ---- */
.seccion-titulo {
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-2); margin: var(--e2) 0 0;
}
.lista-config { display: flex; flex-direction: column; gap: var(--e2); }
.fila-config {
  display: flex; align-items: center; gap: var(--e2);
  background: var(--superficie); border: none; box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  padding: var(--e4);
  transition: background var(--transicion);
}
.fila-config:active { background: var(--superficie-alta); }
.fila-config__info { flex: 1; min-width: 0; }
.fila-config__nombre { font-weight: 700; }
.fila-config__meta { font-size: var(--t-xs); color: var(--texto-2); margin-top: 2px; }
.fila-config__acciones { display: flex; gap: var(--e1); }

/* ---- Central de Enlaces (Fase 17, §3): bento de enlaces de reserva
   arriba de "Negocio y reglas de agenda". Cristal sutil (--superficie +
   --desenfoque, el mismo lenguaje visual del resto del panel) en vez de
   un bloque plano, porque esto es lo primero que un dueño copia y pega
   en su bio de Instagram -- merece sentirse como el producto premium que
   vende la landing, no como un formulario más. ---- */
.enlaces-bento { display: flex; flex-direction: column; gap: var(--e3); margin-bottom: var(--e5); }
.enlace-tarjeta {
  position: relative;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  padding: var(--e4);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  display: flex; flex-direction: column; gap: var(--e2);
}
.enlace-tarjeta--destacada {
  border-color: color-mix(in srgb, var(--acento) 45%, var(--borde));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--acento) 20%, transparent);
}
.enlace-tarjeta__insignia {
  align-self: flex-start;
  background: color-mix(in srgb, var(--acento) 16%, transparent); color: var(--acento);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  padding: 3px 10px; border-radius: var(--r-full);
}
.enlace-tarjeta__titulo { font-size: var(--t-m); font-weight: 800; }
.enlace-tarjeta__subtitulo { font-size: var(--t-xs); color: var(--texto-2); line-height: 1.5; }
.enlace-tarjeta__url {
  display: flex; align-items: center; gap: var(--e2);
  background: var(--superficie-alta); border: 1px solid var(--borde); border-radius: var(--r-s);
  padding: var(--e2) var(--e3);
  margin-top: 2px;
}
.enlace-tarjeta__url code {
  flex: 1; min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; color: var(--texto);
  overflow-x: auto; white-space: nowrap; scrollbar-width: none;
}
.enlace-tarjeta__url code::-webkit-scrollbar { display: none; }
.enlace-copiar {
  position: relative;
  flex-shrink: 0; width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-s); border: 1px solid var(--borde); background: var(--superficie);
  font-size: 15px; transition: transform var(--transicion), background var(--transicion);
}
.enlace-copiar:active { transform: scale(.9); background: var(--superficie-alta); }
.enlace-copiar__tooltip {
  position: absolute; bottom: calc(100% + 6px); right: 0;
  background: #111827; color: #fff;
  font-size: 11px; font-weight: 700; white-space: nowrap;
  padding: 4px 9px; border-radius: var(--r-s);
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
}
.enlace-copiar__tooltip.visible { opacity: 1; transform: translateY(0); }

@media (min-width: 520px) {
  .enlaces-bento { flex-direction: row; align-items: stretch; }
  .enlace-tarjeta { flex: 1; }
}

/* ---- Mini-CRM (Fase 16, §1): tab Clientes -- lista de tarjetas + ficha
   con historial. Reutiliza .lista-config/.fila-config/.resumen-grid del
   resto del panel, así que solo hacen falta las piezas nuevas: el avatar
   de iniciales y el encabezado del perfil. ---- */
.cliente-tarjeta {
  display: flex; align-items: center; gap: var(--e3); width: 100%;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-l);
  padding: var(--e3); text-align: left;
  transition: background var(--transicion), transform var(--transicion);
}
.cliente-tarjeta:active { background: var(--superficie-alta); transform: scale(.99); }
.cliente-tarjeta__avatar, .cliente-perfil__avatar {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-full); background: var(--brand-color); color: var(--text-on-cta);
  font-weight: 800;
}
.cliente-tarjeta__avatar { width: 44px; height: 44px; font-size: var(--t-s); }
.cliente-tarjeta__info { flex: 1; min-width: 0; }
.cliente-tarjeta__nombre { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cliente-tarjeta__meta { font-size: var(--t-xs); color: var(--texto-2); margin-top: 2px; }
.cliente-tarjeta__visitas { flex-shrink: 0; text-align: center; line-height: 1.2; }
.cliente-tarjeta__visitas strong { display: block; font-size: var(--t-l); }
.cliente-tarjeta__visitas span { font-size: 10px; color: var(--texto-3); text-transform: uppercase; letter-spacing: .03em; }

.cliente-perfil { display: flex; flex-direction: column; align-items: center; gap: var(--e2); text-align: center; padding: var(--e3) 0; }
.cliente-perfil__avatar { width: 72px; height: 72px; font-size: var(--t-xl); }
.cliente-perfil__nombre { font-size: var(--t-l); }
.cliente-perfil__telefono { color: var(--texto-2); font-size: var(--t-s); margin-top: -8px; }
.cliente-perfil .boton { width: auto; padding: 0 var(--e5); margin-top: var(--e2); }

.boton-icono {
  width: 36px; height: 36px; border-radius: var(--r-s); border: none;
  background: var(--superficie-alta); color: var(--texto-2); display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background var(--transicion), transform var(--transicion);
}
.boton-icono:active { transform: scale(.92); background: var(--borde); }
/* Fase 23 (refactor QA): #admin-boton-notificaciones nunca se esconde -- solo cambia de color cuando la suscripción push ya está activa. */
#admin-boton-notificaciones.es-activo { color: var(--exito); }
.icono { display: inline-block; flex-shrink: 0; }
.menu-mas { display: flex; flex-direction: column; gap: var(--e2); }
.menu-mas__item {
  display: flex; align-items: center; gap: var(--e3); min-height: var(--tap-min);
  background: var(--superficie); border: none; box-shadow: var(--sombra-ultra-suave); border-radius: var(--r-l);
  padding: var(--e3) var(--e4); text-align: left; font-weight: 600;
  transition: background var(--transicion), transform var(--transicion);
}
.menu-mas__item:active { background: var(--superficie-alta); transform: scale(.98); }
.menu-mas__item .icono { flex-shrink: 0; color: var(--texto-2); }
.menu-mas__item.soporte-vip .icono { color: inherit; }

/* ---- Acciones rápidas (§7.5): tiles de color en vez de botones planos,
   una acción de negocio distinta = un acento distinto, escaneable de un
   vistazo. ---- */
.acciones-rapidas { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e3); }
.accion-rapida {
  min-height: 92px; border-radius: var(--r-l); border: 1px solid var(--borde);
  background: var(--superficie-alta);
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  padding: var(--e3) var(--e4); text-align: left;
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.accion-rapida:active { transform: scale(.96); }
.accion-rapida__icono { font-size: 22px; line-height: 1; margin-bottom: 2px; }
.accion-rapida__texto { font-weight: 700; font-size: var(--t-s); color: var(--texto); }
.accion-rapida__subtexto { font-size: 12px; font-weight: 500; color: var(--texto-sutil); line-height: 1.3; }
.accion-rapida--acento { background: color-mix(in srgb, var(--brand-color) 16%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--brand-color) 38%, transparent); }
.accion-rapida--acento .accion-rapida__texto { color: color-mix(in srgb, var(--brand-color) 85%, var(--texto)); }
.accion-rapida--morado { background: color-mix(in srgb, var(--morado) 16%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--morado) 38%, transparent); }
.accion-rapida--morado .accion-rapida__texto { color: color-mix(in srgb, var(--morado) 78%, var(--texto)); }
.accion-rapida--peligro { background: color-mix(in srgb, var(--peligro) 14%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--peligro) 35%, transparent); }
.accion-rapida--peligro .accion-rapida__texto { color: color-mix(in srgb, var(--peligro) 80%, var(--texto)); }
.accion-rapida--alerta { background: color-mix(in srgb, var(--alerta) 16%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--alerta) 38%, transparent); }
.accion-rapida--alerta .accion-rapida__texto { color: color-mix(in srgb, var(--alerta) 80%, var(--texto)); }

.dia-semana-editor { display: flex; flex-direction: column; gap: var(--e2); }
.dia-semana-fila { border: 1px solid var(--borde); border-radius: var(--r-m); padding: var(--e3); }
.dia-semana-fila__encabezado { display: flex; align-items: center; justify-content: space-between; }
.rango-horario { display: flex; align-items: center; gap: var(--e2); margin-top: var(--e2); }
.rango-horario input[type="time"] {
  min-height: var(--tap-min); background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--r-s); padding: var(--e2); color: var(--texto); font-size: var(--t-s);
}

.interruptor { position: relative; display: inline-block; width: 44px; height: 26px; flex-shrink: 0; }
.interruptor input { opacity: 0; width: 0; height: 0; }
.interruptor__deslizador {
  position: absolute; inset: 0; background: var(--borde); border-radius: var(--r-full); transition: var(--transicion); cursor: pointer;
}
.interruptor__deslizador::before {
  content: ""; position: absolute; width: 20px; height: 20px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: var(--transicion);
}
.interruptor input:checked + .interruptor__deslizador { background: var(--acento); }
.interruptor input:checked + .interruptor__deslizador::before { transform: translateX(18px); }

/* ---- Fase 9 · Moderación de reseñas (panel admin) ---- */
.resena-tarjeta {
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-l);
  padding: var(--e3); display: flex; flex-direction: column; gap: var(--e2);
}
.resena-tarjeta--privada { border-left: 3px solid var(--texto-3); }
.resena-tarjeta__cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--e3); }
.resena-tarjeta__estrellas { color: var(--alerta); font-size: var(--t-l); letter-spacing: 1px; }
.resena-tarjeta__meta { font-size: var(--t-xs); color: var(--texto-2); margin-top: 2px; }
.resena-tarjeta__insignia {
  font-size: 10px; font-weight: 700; color: var(--texto-2); background: var(--superficie-alta);
  padding: 2px var(--e2); border-radius: var(--r-full); white-space: nowrap;
}
.resena-tarjeta__comentario { font-size: var(--t-s); color: var(--texto); line-height: 1.4; }
.resena-tarjeta__eliminar { align-self: flex-start; min-height: auto; padding: 0; color: var(--peligro); }

/* ==========================================================================
   FASE 9 · PORTALES PÚBLICOS: estado de reserva y Review-Gate. Reutilizan
   el mismo shell/tokens del embudo (.app-shell, .pantalla, .tarjeta-resumen).
   ========================================================================== */

/* ---- /estado/{token}: insignia grande de estado ---- */
.estado-insignia {
  align-self: center; text-align: center; padding: var(--e3) var(--e5);
  border-radius: var(--r-full); font-weight: 800; font-size: var(--t-m);
  background: var(--superficie-alta); color: var(--texto-2);
}
.estado-insignia.confirmada { background: color-mix(in srgb, var(--exito) 22%, transparent); color: var(--exito); }
.estado-insignia.pendiente_abono, .estado-insignia.pendiente_aprobacion, .estado-insignia.retenida { background: color-mix(in srgb, var(--alerta) 22%, transparent); color: var(--alerta); }
.estado-insignia.completada { background: color-mix(in srgb, var(--acento) 22%, transparent); color: var(--acento); }
.estado-insignia.cancelada_admin, .estado-insignia.cancelada_cliente, .estado-insignia.no_show, .estado-insignia.expirada { background: color-mix(in srgb, var(--peligro) 22%, transparent); color: var(--peligro); }

/* ---- /gracias/{token}: 5 estrellas interactivas ---- */
.selector-estrellas { display: flex; justify-content: center; gap: var(--e2); }
.selector-estrellas__estrella {
  background: none; border: none; font-size: 44px; line-height: 1; color: var(--borde);
  transition: transform var(--transicion), color var(--transicion); padding: var(--e1);
}
.selector-estrellas__estrella:active { transform: scale(.9); }
.selector-estrellas__estrella.activa { color: var(--alerta); }
.resena-gracias { text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--e4); padding-top: var(--e6); }

/* ---- Muro de la Fama (catálogo público, §10.4): bottom sheet con reseñas
   visibles. El disparador (.boton-ver-resenas) se estiliza en el bloque
   §Vitrina Viva, junto al encabezado flotante del que forma parte. ---- */
#muro-fama-sheet { max-width: 480px; } /* el embudo público es 480px (Fase 20 §3), no los 720px del panel admin */
.muro-fama-lista { display: flex; flex-direction: column; gap: var(--e3); max-height: 60vh; overflow-y: auto; }
.muro-fama-tarjeta {
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-m);
  padding: var(--e3); display: flex; flex-direction: column; gap: var(--e1);
}
.muro-fama-tarjeta__estrellas { color: var(--alerta); font-size: var(--t-m); letter-spacing: 1px; }
.muro-fama-tarjeta__nombre { font-weight: 700; font-size: var(--t-s); }

/* ==========================================================================
   FASE 10 · FACTURACIÓN / PAYWALL (/admin/facturacion). Página completa
   (no vive dentro del SPA de .admin-panel): el paywall debe funcionar
   incluso si el negocio nunca llegó a cargar admin.js. Misma paleta que el
   resto del panel; la "autoridad" viene del orden visual, no de otro tema.
   ========================================================================== */
.factura-shell {
  max-width: 480px; margin: 0 auto; min-height: 100vh;
  display: flex; flex-direction: column; gap: var(--e5);
  padding: var(--e5) var(--e4) calc(var(--e7) + var(--seguro-abajo));
}
.factura-encabezado { display: flex; align-items: center; justify-content: space-between; }
.factura-marca { font-size: var(--t-s); font-weight: 700; color: var(--acento); text-transform: uppercase; letter-spacing: .04em; }

/* ---- Banner de estado: trial / vencida / activa ---- */
.factura-estado {
  border-radius: var(--r-m); border: 1px solid var(--borde); background: var(--superficie);
  padding: var(--e4); display: flex; flex-direction: column; gap: var(--e1);
}
.factura-estado__titulo { font-weight: 800; font-size: var(--t-m); }
.factura-estado__detalle { font-size: var(--t-s); color: var(--texto-2); }
.factura-estado--vencida { background: color-mix(in srgb, var(--peligro) 16%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--peligro) 40%, transparent); }
.factura-estado--vencida .factura-estado__titulo { color: var(--peligro); }
.factura-estado--trial { background: color-mix(in srgb, var(--alerta) 14%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--alerta) 38%, transparent); }
.factura-estado--trial .factura-estado__titulo { color: var(--alerta); }
.factura-estado--activa { background: color-mix(in srgb, var(--exito) 14%, var(--superficie-alta)); border-color: color-mix(in srgb, var(--exito) 38%, transparent); }
.factura-estado--activa .factura-estado__titulo { color: var(--exito); }

/* ---- Pricing card: Plan Pro ---- */
.factura-plan {
  position: relative;
  border-radius: var(--r-xl); border: 1px solid var(--borde); background: var(--superficie);
  padding: var(--e6) var(--e5) var(--e5); display: flex; flex-direction: column; gap: var(--e4);
  box-shadow: var(--sombra);
}
.factura-plan--destacado {
  border-color: var(--acento);
  background: var(--superficie-alta);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--acento) 35%, transparent), var(--sombra);
}
.factura-plan__insignia {
  position: absolute; top: -14px; left: var(--e5);
  background: var(--acento); color: var(--text-on-cta);
  font-size: 12px; font-weight: 800; letter-spacing: .02em;
  padding: var(--e1) var(--e3); border-radius: var(--r-full);
}
.factura-plan__nombre { font-size: var(--t-xl); font-weight: 800; }
.factura-plan__resumen { font-size: var(--t-s); color: var(--texto-2); }
.factura-plan__precio { display: flex; align-items: baseline; gap: var(--e1); }
.factura-plan__precio-valor { font-size: clamp(32px, 9vw, 44px); font-weight: 800; letter-spacing: -.02em; }
.factura-plan__precio-periodo { font-size: var(--t-s); color: var(--texto-2); }

/* ---- Sellos de confianza ---- */
.factura-sellos {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e2);
  text-align: center;
}
.factura-sello {
  display: flex; flex-direction: column; align-items: center; gap: var(--e1);
  padding: var(--e3) var(--e1);
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-m);
}
.factura-sello__icono { font-size: 22px; line-height: 1; }
.factura-sello__texto { font-size: 11px; font-weight: 600; color: var(--texto-2); line-height: 1.3; }

.factura-pie { text-align: center; font-size: var(--t-s); color: var(--texto-2); }
.muro-fama-tarjeta__comentario { font-size: var(--t-s); color: var(--texto-2); line-height: 1.4; }

/* ---- Fase 13 (§4, "Refactorización Visual"): sombra suave consistente
   para tarjetas/tiles que hoy solo llevaban borde plano — sin tocar sus
   reglas existentes, solo se suma la elevación. Fase 21 (§1): .kpi-tarjeta
   y .menu-mas__item ya tienen su propia sombra ultra-suave (más arriba,
   reemplazando su borde por completo), así que salen de este combo. ---- */
.resena-tarjeta, .admin-login__tarjeta, .tarjeta-resumen,
.chip-recurso, .pildora-fecha, .tarjeta-industria,
.factura-cupon, .factura-sello, .sa-tabla-envoltura, .paleta-swatch {
  box-shadow: var(--sombra-suave);
}

/* ==========================================================================
   §VITRINA VIVA — la landing pública del negocio (embudo.php, paso 0).

   Reemplaza por completo al bloque "Embudo de Ventas Premium" (Fase 18.1) y
   a las pestañas del Bottom Nav (Fase 20 §3). El diagnóstico que lo motiva:
   en un vertical 100% visual (spa, lashista, barbería premium) el producto
   que se compra es un RESULTADO QUE SE VE, y la landing anterior escondía
   la galería detrás de una pestaña -- es decir, escondía el producto.

   Tres reglas rigen todo lo que sigue:

   1. LA FOTO MANDA. El hero es una imagen a sangre completa y el portafolio
      es la primera sección después de él, en mosaico asimétrico. La
      asimetría no es capricho: una grilla uniforme se escanea, un mosaico
      con jerarquía se recorre.
   2. RITMO EDITORIAL. Cada sección abre con un "kicker" (etiqueta pequeña
      en versalitas del color de marca) y un titular grande. Esa cadencia
      repetida es lo que separa un sitio de lujo de una pila de bloques.
   3. NADA DE TINTAS FIJAS. Cada color aquí sale de un token que
      paletaVitrina() (PHP) derivó del hex de marca del negocio -- incluido
      el velo del hero. Un hex nuevo en el panel repinta la landing entera
      sin tocar una línea de este archivo.
   ========================================================================== */

/* ---- Escala tipográfica de la vitrina. Deliberadamente más amplia que la
   del panel admin: la landing tiene que respirar como una revista, no
   densificar como un dashboard. ---- */
.pantalla-vitrina {
  --t-hero: clamp(2rem, 9vw, 3.25rem);
  --t-seccion: clamp(1.5rem, 6vw, 2.125rem);
  --t-cuerpo: clamp(.95rem, 3.6vw, 1.0625rem);
  /* Aire entre secciones: el lujo se comunica con espacio vacío. */
  --aire: clamp(3.5rem, 12vw, 5.5rem);
  --margen: var(--e5);

  flex: 0 1 auto;
  gap: 0;
  /* El hero arranca pegado al borde superior (el encabezado flota encima) y
     las secciones ponen su propio padding lateral: nada full-bleed necesita
     pelear con márgenes negativos, como sí pasaba en el diseño anterior.
     El hueco para la barra fija de "Reservar" NO se reserva aquí sino en el
     padding del pie (.vitrina-pie): puesto aquí dejaba una franja del color
     de fondo por debajo del pie, y el pie tiene su propio tono -- se veía
     como si la página terminara dos veces. */
  padding: 0;
}

/* ---- Encabezado flotante: sobre el hero es transparente (no le roba 60px
   a la foto) y se vuelve cristal solo al hacer scroll -- vitrina.js suma
   .es-solido. Sin hero detrás (Plan Básico/Enlace Directo) el encabezado
   nunca lleva --flotante y se comporta como la barra sólida de siempre. ---- */
.encabezado--flotante {
  position: fixed;
  top: 0; left: 0; right: 0;
  max-width: 480px;
  margin: 0 auto;
  background: transparent;
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  color: #fff;
  transition: background var(--transicion), border-color var(--transicion), backdrop-filter var(--transicion);
}
.encabezado--flotante .encabezado__estado { color: rgba(255, 255, 255, .78); }
.encabezado--flotante .encabezado__logo {
  background: rgba(255, 255, 255, .16);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .35);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.encabezado--flotante.es-solido {
  background: color-mix(in srgb, var(--fondo) 82%, transparent);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  border-bottom-color: var(--borde);
  color: var(--texto);
}
.encabezado--flotante.es-solido .encabezado__estado { color: var(--texto-2); }
.encabezado--flotante.es-solido .encabezado__logo {
  background: var(--acento); color: var(--text-on-cta); border-color: transparent;
}

/* ---- Sello de rating del encabezado: una cifra real (4,9) pesa más que la
   palabra "reseñas", y ocupa la mitad del ancho. ---- */
.boton-ver-resenas {
  display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  background: var(--superficie-alta); border: 1px solid var(--borde); border-radius: var(--r-full);
  padding: var(--e2) var(--e3); font-size: var(--t-s); font-weight: 800; color: var(--texto);
  line-height: 1;
}
.boton-ver-resenas__estrella { color: #E8B45A; font-size: var(--t-m); }
/* Cifras tabulares: al cambiar de 4,9 a 5,0 la píldora no debe "bailar". */
.boton-ver-resenas__nota { font-variant-numeric: tabular-nums; }
.encabezado--flotante .boton-ver-resenas {
  background: rgba(255, 255, 255, .16);
  border-color: rgba(255, 255, 255, .32);
  color: #fff;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.encabezado--flotante.es-solido .boton-ver-resenas {
  background: var(--superficie-alta); border-color: var(--borde); color: var(--texto);
}

/* ==========================================================================
   1 · HERO CINEMATOGRÁFICO
   ========================================================================== */
.vitrina-hero {
  position: relative;
  min-height: 88vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  isolation: isolate;
  color: #fff;
}
/* svh evita el salto clásico de iOS cuando la barra de Safari se retrae. */
@supports (height: 100svh) {
  .vitrina-hero { min-height: min(88svh, 820px); }
}
.vitrina-hero--sin-foto {
  background: linear-gradient(155deg, var(--primario) 0%, color-mix(in srgb, var(--primario) 45%, var(--acento) 55%) 100%);
}
.vitrina-hero__media { position: absolute; inset: 0; z-index: -2; }
.vitrina-hero__media img {
  width: 100%; height: 100%; object-fit: cover;
  /* Ken Burns lentísimo (24s): el movimiento no debe leerse como animación,
     solo debe hacer que la foto se sienta viva en vez de impresa. */
  animation: vitrina-ken-burns 24s ease-in-out infinite alternate;
  transform-origin: center 40%;
}
@keyframes vitrina-ken-burns {
  from { transform: scale(1); }
  to   { transform: scale(1.09); }
}
.vitrina-hero__velo {
  position: absolute; inset: 0; z-index: -1;
  /* Velo TEÑIDO con el color primario del negocio (--velo-*, calculado en
     PHP), nunca un negro plano: sobre la foto se lee como la oscuridad de
     esa marca y no como el filtro de una plantilla genérica. */
  background: linear-gradient(180deg, var(--velo-1) 0%, var(--velo-2) 55%, var(--velo-3) 100%);
}
.vitrina-hero__contenido {
  position: relative;
  padding: var(--e9) var(--margen) var(--e8);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--e3);
}
.vitrina-hero__logo {
  width: 76px; height: 76px; border-radius: var(--r-m);
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, .9);
  background: rgba(255, 255, 255, .15);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
  margin-bottom: var(--e1);
}
.vitrina-hero__oferta {
  background: rgba(255, 255, 255, .95);
  color: #111827;
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  padding: 7px 16px; border-radius: var(--r-full);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .3);
}
.vitrina-hero__titulo {
  font-size: var(--t-hero);
  font-weight: 800;
  line-height: 1.04;
  /* El tracking negativo es lo que hace que un titular grande se lea
     "diseñado" y no "grande por accidente". */
  letter-spacing: -.03em;
  color: #fff;
  text-shadow: 0 2px 24px rgba(0, 0, 0, .45);
  text-wrap: balance;
}
.vitrina-hero__subtitulo {
  font-size: var(--t-cuerpo);
  color: rgba(255, 255, 255, .92);
  line-height: 1.6; max-width: 40ch;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .4);
}
.vitrina-hero__meta { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e1); }
.sello-hero {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255, 255, 255, .14);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .24);
  border-radius: var(--r-full);
  padding: 7px 14px;
  font-size: var(--t-xs); color: rgba(255, 255, 255, .92);
}
.sello-hero strong { font-size: var(--t-s); font-weight: 800; color: #fff; }
.sello-hero__estrellas { color: #E8B45A; letter-spacing: 1px; }
.sello-hero--sutil { max-width: 100%; }
.sello-hero--sutil span:last-child {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 22ch;
}
.vitrina-hero__acciones {
  display: flex; flex-wrap: wrap; gap: var(--e2);
  width: 100%; margin-top: var(--e3);
}
.vitrina-hero__acciones .boton { flex: 1 1 160px; width: auto; }

/* (Aquí vivía una "pista de scroll" animada al pie del hero. Se retiró: con
   el contenido anclado abajo chocaba visualmente con los botones, y la
   franja de confianza ya asoma sobre el pliegue -- que es una señal de "hay
   más abajo" mucho más honesta que una flecha decorativa.) */

/* ==========================================================================
   2 · FRANJA DE CONFIANZA — solo cifras que salen de la BD del negocio
   ========================================================================== */
.franja-confianza {
  display: flex;
  justify-content: space-around;
  align-items: stretch;
  gap: var(--e2);
  padding: var(--e5) var(--margen);
  background: var(--fondo-elevado);
  border-bottom: 1px solid var(--borde);
}
.franja-confianza__item {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  text-align: center; flex: 1; min-width: 0;
}
.franja-confianza__valor {
  font-size: clamp(1.25rem, 5.5vw, 1.6rem); font-weight: 800;
  letter-spacing: -.02em; color: var(--acento); line-height: 1.1;
}
.franja-confianza__etiqueta {
  font-size: 11px; color: var(--texto-3); line-height: 1.25; font-weight: 600;
}

/* ==========================================================================
   Cabecera común de sección (kicker + titular + intro)
   ========================================================================== */
.vitrina-seccion {
  padding: var(--aire) var(--margen) 0;
  /* El encabezado flota fijo sobre la página: sin este margen de scroll,
     saltar a #portafolio desde el hero dejaba el kicker y media línea del
     titular escondidos DEBAJO de la barra. */
  scroll-margin-top: 76px;
}
.vitrina-seccion__kicker {
  font-size: 11px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .16em;
  color: var(--acento);
  margin-bottom: var(--e2);
}
.vitrina-seccion__titulo {
  font-size: var(--t-seccion); font-weight: 800;
  letter-spacing: -.025em; line-height: 1.12;
  text-wrap: balance;
}
.vitrina-seccion__intro {
  margin-top: var(--e3);
  font-size: var(--t-s); color: var(--texto-2); line-height: 1.65; max-width: 46ch;
}

/* ==========================================================================
   3 · PORTAFOLIO — el corazón de la landing
   Mosaico asimétrico: 1 pieza a todo el ancho + 4 en cuadrícula. Las fotos
   restantes no se duplican en el DOM; la última pieza avisa con "+N" y el
   visor a pantalla completa las trae desde el JSON.
   ========================================================================== */
.mosaico {
  margin-top: var(--e5);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--e2);
}
.mosaico__pieza {
  position: relative;
  padding: 0; border: none; background: var(--fondo-hundido);
  border-radius: var(--r-m);
  overflow: hidden;
  aspect-ratio: 1;
  cursor: pointer;
  box-shadow: var(--sombra-ultra-suave);
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.mosaico__pieza--destacada { grid-column: span 2; aspect-ratio: 4 / 3; border-radius: var(--r-l); }
/* Con solo 2 fotos, la segunda también ocupa el ancho completo: media
   cuadrícula huérfana se ve como un error de maquetación, no como diseño. */
.mosaico:has(> :nth-child(2):last-child) .mosaico__pieza:not(.mosaico__pieza--destacada) {
  grid-column: span 2; aspect-ratio: 4 / 3;
}
.mosaico__pieza img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 420ms cubic-bezier(.4, 0, .2, 1);
}
.mosaico__pieza:active { transform: scale(.985); }
@media (hover: hover) {
  .mosaico__pieza:hover { box-shadow: var(--sombra); }
  .mosaico__pieza:hover img { transform: scale(1.06); }
}
.mosaico__pieza:focus-visible { outline: 2px solid var(--acento); outline-offset: 3px; }
/* "+N": la señal magnética clásica -- decir cuántas faltan invita a abrir
   mucho más que un botón que solo dice "ver más". */
.mosaico__mas {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .52);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  color: #fff; font-size: clamp(1.5rem, 7vw, 2rem); font-weight: 800; letter-spacing: -.02em;
}
.vitrina-seccion--portafolio .boton-fantasma--ancho { margin-top: var(--e4); }

/* ---- Botón fantasma: contorno de cristal. Sobre el hero se lee sobre la
   foto; en el cuerpo de la página, sobre el fondo de marca. ---- */
.boton-fantasma {
  background: rgba(255, 255, 255, .12);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .4);
  color: #fff;
  text-decoration: none;
}
.boton-fantasma:active { transform: scale(.97); }
@media (hover: hover) {
  .boton-fantasma:hover { background: rgba(255, 255, 255, .2); }
}
/* Fuera del hero no hay foto detrás: el fantasma toma los tokens de marca. */
.vitrina-seccion .boton-fantasma {
  background: transparent;
  border-color: var(--acento);
  color: var(--acento);
  font-weight: 700;
}
@media (hover: hover) {
  .vitrina-seccion .boton-fantasma:hover { background: var(--marca-lavado); }
}

/* ==========================================================================
   4 · LA CARTA — servicios como menú de spa
   ========================================================================== */
/* Servicio insignia: foto grande, el ancla de deseo y de precio. */
.carta-firma {
  margin-top: var(--e5);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--fondo-elevado);
  border: 1px solid var(--borde);
  box-shadow: var(--sombra-ultra-suave);
}
.carta-firma__media { position: relative; aspect-ratio: 3 / 2; background: var(--fondo-hundido); }
.carta-firma__media img { width: 100%; height: 100%; object-fit: cover; }
.carta-firma__sello {
  position: absolute; top: var(--e3); left: var(--e3);
  background: var(--acento); color: var(--text-on-cta);
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em;
  padding: 6px 12px; border-radius: var(--r-full);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}
.carta-firma__cuerpo { padding: var(--e5); display: flex; flex-direction: column; gap: var(--e2); }
.carta-firma__nombre { font-size: var(--t-l); font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.carta-firma__descripcion { font-size: var(--t-s); color: var(--texto-2); line-height: 1.6; }
.carta-firma__meta { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e1); }
.chip-meta {
  font-size: var(--t-xs); font-weight: 600; color: var(--texto-2);
  background: var(--superficie-alta); border: 1px solid var(--borde);
  padding: 5px 12px; border-radius: var(--r-full); white-space: nowrap;
}
.carta-firma__pie {
  display: flex; align-items: center; gap: var(--e3);
  margin-top: var(--e3);
}
.carta-firma__precio {
  font-size: clamp(1.35rem, 6vw, 1.75rem); font-weight: 700;
  letter-spacing: -.03em; color: var(--acento); white-space: nowrap;
}
.carta-firma__pie .boton { width: auto; flex: 1; min-width: 130px; }

/* ---- Filas de carta. La línea punteada que une nombre y precio es la cita
   tipográfica directa de un menú impreso -- es lo que convierte una lista
   de precios en una carta. ---- */
.carta-lista { margin-top: var(--e5); display: flex; flex-direction: column; }
.carta-item {
  display: flex; align-items: flex-start; gap: var(--e4);
  /* Más aire vertical que un grid de e-commerce a propósito: el espacio en
     blanco entre filas es lo que hace que una lista de precios se lea como
     la carta de un spa de cinco estrellas y no como un catálogo. */
  padding: var(--e6) 0;
  border-bottom: 1px solid var(--linea);
}
.carta-item:first-child { border-top: 1px solid var(--linea); }
.carta-item__miniatura {
  flex: 0 0 auto; width: 72px; height: 72px;
  border-radius: var(--r-m); overflow: hidden;
  background: var(--fondo-hundido);
}
.carta-item__miniatura img { width: 100%; height: 100%; object-fit: cover; }
.carta-item__texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.carta-item__linea { display: flex; align-items: baseline; gap: var(--e2); }
.carta-item__nombre { font-size: var(--t-m); font-weight: 700; letter-spacing: -.01em; }
.carta-item__guia {
  flex: 1;
  border-bottom: 1px dotted var(--texto-3);
  opacity: .7;
  transform: translateY(-4px);
  /* Cuando el nombre del servicio se parte en dos líneas, a la guía solo le
     queda el sobrante de la última: por debajo de este mínimo dejaba de
     leerse como línea de carta y parecía un guion suelto. */
  min-width: var(--e5);
}
/* Semibold + tono de acento (no el mismo negro del nombre): el precio se
   lee como una cifra con carácter propio, la firma tipográfica de una carta
   impresa, no una columna más de la fila. */
.carta-item__precio { font-size: var(--t-m); font-weight: 600; color: var(--acento); white-space: nowrap; }
.carta-item__descripcion { font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.carta-item__pie { display: flex; align-items: center; justify-content: space-between; gap: var(--e3); margin-top: var(--e1); }
.carta-item__meta { font-size: var(--t-xs); color: var(--texto-3); }
.carta-item__accion {
  flex-shrink: 0;
  min-height: 38px; padding: 0 var(--e4);
  border-radius: var(--r-full);
  border: 1px solid var(--acento);
  background: transparent; color: var(--acento);
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .02em;
  transition: background var(--transicion), color var(--transicion), transform var(--transicion);
}
.carta-item__accion:active { transform: scale(.96); }
@media (hover: hover) {
  .carta-item__accion:hover { background: var(--acento); color: var(--text-on-cta); }
}

/* ==========================================================================
   5 · AUTORIDAD — "por qué elegirnos" como HTML del micro-editor del panel
   (negrita/cursiva/listas/párrafos armados a mano por el dueño), no como
   texto plano descompuesto por línea. .about-content es la frontera de
   estilos entre ese HTML y el resto de la landing: negritas con el mismo
   peso/color que un título de sección, párrafos con aire de lectura y
   listas que respetan la jerarquía visual del resto de la vitrina.
   ========================================================================== */
.about-content {
  margin-top: var(--e3);
  max-width: 62ch;
  font-size: var(--t-m);
  line-height: 1.7;
  color: var(--texto-2);
}
.about-content p { margin: 0 0 1.2rem; }
.about-content p:last-child { margin-bottom: 0; }
.about-content b,
.about-content strong { font-weight: 700; color: var(--texto); }
.about-content i,
.about-content em { font-style: italic; }
.about-content ul {
  margin: 0 0 1.2rem;
  padding-left: 1.3em;
  display: flex;
  flex-direction: column;
  gap: var(--e2);
}
.about-content ul:last-child { margin-bottom: 0; }
.about-content li { padding-left: var(--e1); }
.about-content li::marker { color: var(--acento); }

/* ==========================================================================
   6 · TESTIMONIOS — carrusel con scroll-snap
   ========================================================================== */
.testimonios-tira {
  margin-top: var(--e5);
  display: flex; gap: var(--e3);
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  /* Sangra hasta el borde de la pantalla: el carrusel tiene que "salirse"
     para que se lea como deslizable, no como una tarjeta suelta. */
  margin-inline: calc(var(--margen) * -1);
  padding: 2px var(--margen) var(--e2);
  scroll-padding-left: var(--margen);
}
.testimonios-tira::-webkit-scrollbar { display: none; }
.testimonio {
  scroll-snap-align: start;
  flex: 0 0 78%; max-width: 320px;
  margin: 0;
  background: var(--fondo-elevado);
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  padding: var(--e5) var(--e4);
  box-shadow: var(--sombra-ultra-suave);
  display: flex; flex-direction: column; gap: var(--e3);
}
.testimonio__estrellas { font-size: var(--t-s); letter-spacing: 2px; color: #E8B45A; }
.testimonio__estrellas-off { color: var(--texto-3); opacity: .35; }
.testimonio__texto {
  margin: 0;
  font-size: var(--t-s); color: var(--texto); line-height: 1.65; font-style: italic;
}
.testimonio__autor {
  display: flex; align-items: center; gap: var(--e2);
  margin-top: auto;
  font-weight: 700; font-size: var(--t-xs); color: var(--texto-2);
}
.testimonio__avatar {
  width: 30px; height: 30px; border-radius: var(--r-full); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--marca-lavado); color: var(--acento);
  font-size: var(--t-xs); font-weight: 800;
}

/* ==========================================================================
   7 · BOUTIQUE — bento de productos
   ========================================================================== */
.bento-productos { margin-top: var(--e5); display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e3); }
.bento-producto {
  display: flex; flex-direction: column;
  border-radius: var(--r-l); overflow: hidden;
  background: var(--fondo-elevado); border: 1px solid var(--borde);
  box-shadow: var(--sombra-ultra-suave);
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.bento-producto--grande { grid-column: span 2; }
.bento-producto__media {
  position: relative; width: 100%; height: 168px;
  background: var(--fondo-hundido);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.bento-producto--grande .bento-producto__media { height: 220px; }
.bento-producto__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bento-producto__inicial { font-size: var(--t-xl); font-weight: 800; color: var(--texto-3); }
.bento-producto__info { padding: var(--e4); display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.bento-producto__nombre { font-weight: 800; font-size: var(--t-s); line-height: 1.3; }
.bento-producto__descripcion {
  font-size: var(--t-xs); color: var(--texto-2); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.bento-producto__pie { margin-top: auto; padding-top: var(--e2); display: flex; align-items: center; justify-content: space-between; gap: var(--e2); }
.bento-producto__precio { font-weight: 800; font-size: var(--t-m); color: var(--texto); white-space: nowrap; }
.bento-producto__boton {
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  padding: 7px 14px; border-radius: var(--r-full);
  background: transparent; border: 1px solid var(--acento); color: var(--acento);
  white-space: nowrap; text-decoration: none;
  transition: background var(--transicion), color var(--transicion);
}
@media (hover: hover) {
  .bento-producto:hover { transform: translateY(-3px); box-shadow: var(--sombra); }
  .bento-producto__boton:hover { background: var(--acento); color: var(--text-on-cta); }
}

/* ==========================================================================
   8 · FAQ — acordeón nativo <details>, sin una línea de JS
   ========================================================================== */
.faq-acordeon { margin-top: var(--e5); display: flex; flex-direction: column; }
.faq-item {
  border-bottom: 1px solid var(--linea);
  padding: var(--e2) 0;
}
.faq-item:first-child { border-top: 1px solid var(--linea); }
.faq-item summary {
  cursor: pointer; font-weight: 700; font-size: var(--t-m);
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
  min-height: var(--tap-min);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+"; flex-shrink: 0; font-size: 22px; font-weight: 300; color: var(--acento);
  transition: transform var(--transicion);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { margin: 0 0 var(--e3); padding-right: var(--e5); font-size: var(--t-s); color: var(--texto-2); line-height: 1.7; }

/* ==========================================================================
   9 · CIERRE — el último empujón
   ========================================================================== */
.cierre-reserva {
  margin: var(--aire) var(--margen) 0;
  padding: var(--e7) var(--e5);
  border-radius: var(--r-xl);
  background: var(--fondo-elevado);
  border: 1px solid var(--borde);
  box-shadow: var(--sombra-ultra-suave);
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: var(--e3);
}
.cierre-reserva__titulo { font-size: var(--t-seccion); font-weight: 800; letter-spacing: -.025em; line-height: 1.15; text-wrap: balance; }
.cierre-reserva__subtitulo { font-size: var(--t-s); color: var(--texto-2); }
.cierre-reserva__pasos {
  display: flex; align-items: flex-start; justify-content: center; gap: var(--e4);
  width: 100%; margin: var(--e2) 0;
}
.cierre-reserva .boton { max-width: 340px; }
.paso-mini { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; max-width: 100px; }
.paso-mini__num {
  width: 32px; height: 32px; border-radius: var(--r-full);
  background: var(--marca-lavado); color: var(--acento);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: var(--t-s); flex-shrink: 0;
}
.paso-mini span:last-child { font-size: 11px; color: var(--texto-2); line-height: 1.3; }

/* Insignia de escasez: naranja/rojo fijo a propósito (no --acento) -- la
   urgencia se lee igual sin importar la paleta, y no compite con la marca. */
.insignia-escasez {
  display: inline-flex; align-items: center; gap: 4px;
  background: linear-gradient(135deg, #F97316, #EF4444); color: #fff;
  font-size: 12px; font-weight: 800;
  padding: 6px 15px; border-radius: var(--r-full);
  box-shadow: 0 4px 14px color-mix(in srgb, #EF4444 35%, transparent);
  animation: pulso-escasez 1.8s ease-in-out infinite;
}
@keyframes pulso-escasez {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}

/* ==========================================================================
   10 · PIE — dirección, mapa y WhatsApp
   ========================================================================== */
.vitrina-pie {
  margin-top: var(--aire);
  /* El padding inferior absorbe el alto de la barra fija de "Reservar" para
     que el color del pie llegue hasta el borde de la pantalla. */
  padding: var(--e7) var(--margen) calc(var(--e6) + var(--e7) + var(--seguro-abajo) + 24px);
  border-top: 1px solid var(--borde);
  background: var(--fondo-elevado);
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: var(--e2);
}
.vitrina-pie__marca { font-size: var(--t-l); font-weight: 800; letter-spacing: -.02em; }
.vitrina-pie__dato { font-size: var(--t-s); color: var(--texto-2); line-height: 1.6; max-width: 34ch; }
.vitrina-pie__enlaces { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--e2); margin-top: var(--e2); }
.vitrina-pie__enlace {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--tap-min); padding: 0 var(--e4);
  border-radius: var(--r-full);
  border: 1px solid var(--borde); background: var(--superficie-alta);
  font-size: var(--t-s); font-weight: 700; color: var(--texto); text-decoration: none;
}
.vitrina-pie__legal { margin-top: var(--e3); font-size: var(--t-xs); color: var(--texto-3); }
.vitrina-pie__legal a { color: var(--texto-3); }

/* ==========================================================================
   VISOR DE PORTAFOLIO — pantalla completa, con swipe
   Mirar el trabajo y agendarlo tienen que ser el mismo gesto: por eso el
   visor lleva su propio CTA fijo abajo.
   ========================================================================== */
.visor {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(8, 9, 12, .97);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  display: flex; align-items: center; justify-content: center;
  animation: visor-entrar 220ms ease;
}
@keyframes visor-entrar { from { opacity: 0; } to { opacity: 1; } }
.visor__lienzo {
  position: absolute; inset: 0;
  display: flex;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior: contain;
}
.visor__lienzo::-webkit-scrollbar { display: none; }
.visor__diapositiva {
  flex: 0 0 100%; scroll-snap-align: center;
  display: flex; align-items: center; justify-content: center;
  padding: calc(var(--e7) + var(--e4)) var(--e4) calc(var(--e9) + var(--seguro-abajo));
}
.visor__diapositiva img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  border-radius: var(--r-m);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .6);
}
.visor__cerrar {
  position: absolute; top: calc(var(--e4) + env(safe-area-inset-top, 0px)); right: var(--e4); z-index: 2;
  width: 44px; height: 44px; border-radius: var(--r-full);
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .12);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: #fff; font-size: 17px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
/* Las flechas son para puntero/teclado: en táctil el gesto natural es el
   swipe del propio scroll-snap, y dos botones flotantes solo taparían foto. */
.visor__flecha {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 48px; height: 48px; border-radius: var(--r-full);
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .12);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: #fff; font-size: 28px; line-height: 1;
  display: none; align-items: center; justify-content: center;
}
.visor__flecha--anterior { left: var(--e4); }
.visor__flecha--siguiente { right: var(--e4); }
@media (hover: hover) and (min-width: 640px) {
  .visor__flecha { display: flex; }
}
.visor__pie {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: var(--e4) var(--e4) calc(var(--e4) + var(--seguro-abajo));
  display: flex; align-items: center; gap: var(--e3);
  background: linear-gradient(180deg, transparent, rgba(8, 9, 12, .85) 45%);
}
.visor__contador {
  flex-shrink: 0;
  font-size: var(--t-s); font-weight: 700; color: rgba(255, 255, 255, .8);
  font-variant-numeric: tabular-nums;
}
.visor__cta { flex: 1; width: auto; max-width: 260px; margin-left: auto; }

/* ==========================================================================
   MICRO-INTERACCIONES · revelado al hacer scroll
   El estado inicial solo se aplica cuando el JS confirma que va a
   observar (.js-revelar en <html>): si el script falla o no carga, el
   contenido nunca queda invisible por culpa de una animación que no llegó.
   ========================================================================== */
.js-revelar .revelar {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 620ms cubic-bezier(.22, 1, .36, 1), transform 620ms cubic-bezier(.22, 1, .36, 1);
  will-change: opacity, transform;
}
.js-revelar .revelar.es-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .vitrina-hero__media img,
  .insignia-escasez { animation: none; }
  .visor { animation: none; }
  .js-revelar .revelar { opacity: 1; transform: none; transition: none; }
  .mosaico__pieza img { transition: none; }
}

/* ==========================================================================
   Escritorio: la vitrina se ensancha a 720px (el micro-site "app" de 480px
   se veía como una tira estrecha en un portátil, justo donde el dueño del
   negocio le muestra su landing a un cliente). El motor de reservas
   mantiene sus 480px: es un formulario, y un formulario ancho se llena
   peor.
   ========================================================================== */
@media (min-width: 760px) {
  #app[data-modo-sheet="1"] { max-width: 720px; }
  #app[data-modo-sheet="1"] .encabezado--flotante { max-width: 720px; }
  .pantalla-vitrina { --margen: var(--e6); }
  .mosaico { grid-template-columns: repeat(3, 1fr); }
  .mosaico__pieza--destacada { grid-column: span 3; aspect-ratio: 16 / 9; }
  .mosaico:has(> :nth-child(2):last-child) .mosaico__pieza:not(.mosaico__pieza--destacada) { grid-column: span 3; }
  .carta-firma { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
  .carta-firma__media { aspect-ratio: auto; height: 100%; }
  .carta-firma__cuerpo { justify-content: center; }
  .bento-productos { grid-template-columns: repeat(3, 1fr); }
  .bento-producto--grande { grid-column: span 3; }
  .bento-producto--grande .bento-producto__media { height: 280px; }
}

/* ---- Panel admin: subida de imagen del Site Builder (logo/banner/producto).
   Miniatura + botón, con un spinner mientras el servidor convierte a WebP. ---- */
.subida-imagen { display: flex; align-items: center; gap: var(--e3); }
.subida-imagen__preview {
  position: relative;
  width: 72px; height: 72px;
  border-radius: var(--r-m);
  background: var(--superficie-alta);
  border: 1px dashed var(--borde);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
  color: var(--texto-3); font-size: 22px;
}
.subida-imagen--banner .subida-imagen__preview { width: 128px; height: 72px; border-radius: var(--r-s); }
.subida-imagen__preview img { width: 100%; height: 100%; object-fit: cover; }
.subida-imagen__preview.cargando img { opacity: .35; }
.subida-imagen__preview.cargando::after {
  content: "";
  position: absolute; width: 22px; height: 22px;
  border: 3px solid var(--borde); border-top-color: var(--acento);
  border-radius: 50%;
  animation: girar-spinner .8s linear infinite;
}
@keyframes girar-spinner { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .subida-imagen__preview.cargando::after { animation: none; } }
.subida-imagen__acciones { display: flex; flex-direction: column; gap: 4px; }
.subida-imagen__estado { font-size: var(--t-xs); color: var(--texto-2); }
.subida-imagen__estado.error { color: var(--peligro); }

/* ---- Panel admin: miniatura de fila -- variante de .fila-config con
   imagen, compartida por el catálogo de productos y de servicios. ---- */
.fila-config__miniatura {
  width: 44px; height: 44px; border-radius: var(--r-s); flex-shrink: 0;
  background: var(--superficie-alta); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  color: var(--texto-3); font-weight: 700;
}
.fila-config__miniatura img { width: 100%; height: 100%; object-fit: cover; }
.fila-producto.inactivo { opacity: .55; }

/* ---- Panel admin: grilla de la Galería de resultados. Los botones de
   acción quedan siempre visibles (nunca detrás de :hover) -- este es un
   panel mobile-first, sin puntero, así que ocultarlos sería inutilizarlos
   en el uso real (táctil). ---- */
.galeria-admin-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e2); }
.galeria-admin-item {
  display: flex; flex-direction: column;
  border-radius: var(--r-m); overflow: hidden;
  background: var(--superficie-alta); border: 1px solid var(--borde);
}
.galeria-admin-item img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.galeria-admin-item__acciones {
  display: flex; align-items: center; justify-content: center; gap: 2px;
  padding: 4px; background: var(--superficie);
}

/* ---- Fase 4 ("Catálogo de Servicios" como módulo del Site Builder): grilla
   de tarjetas foto-primero para gestionar servicios -- reemplaza la fila de
   texto plana solo en Servicios (Productos sigue usando .fila-config, sin
   cambios). El eco de la vista pública ahora es .carta-firma (§Vitrina
   Viva): foto arriba, cuerpo abajo, para que el dueño reconozca en el panel
   la misma pieza que verá su cliente. Acciones siempre visibles (nunca solo
   en :hover): panel mobile-first, sin puntero. ---- */
.catalogo-servicios-admin { display: grid; grid-template-columns: 1fr; gap: var(--e3); }
@media (min-width: 520px) {
  .catalogo-servicios-admin { grid-template-columns: repeat(2, 1fr); }
}
.tarjeta-servicio-admin {
  display: flex; flex-direction: column;
  border-radius: var(--r-l); overflow: hidden;
  background: var(--superficie); border: 1px solid var(--borde);
  box-shadow: var(--sombra-ultra-suave);
}
.tarjeta-servicio-admin__media {
  width: 100%; height: 130px; background: var(--superficie-alta);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.tarjeta-servicio-admin__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tarjeta-servicio-admin__inicial { font-size: var(--t-xl); font-weight: 800; color: var(--texto-3); }
.tarjeta-servicio-admin__cuerpo { padding: var(--e3) var(--e4) 0; }
.tarjeta-servicio-admin__nombre { font-weight: 700; }
.tarjeta-servicio-admin__meta { font-size: var(--t-xs); color: var(--texto-2); margin-top: 2px; }
.tarjeta-servicio-admin__acciones { display: flex; gap: var(--e1); padding: var(--e3) var(--e4); }
.tarjeta-servicio-admin__acciones .boton-icono { flex: 1; }

/* ==========================================================================
   FASE 20 — Inducción del dueño del negocio (§1-2)
   ========================================================================== */

/* ---- Texto de ayuda estratégico bajo un campo del Constructor de Sitio:
   nunca reemplaza el label, solo empuja al dueño hacia una mejor decisión
   de copywriting en el momento exacto en que la está tomando. ---- */
.campo__ayuda { font-size: var(--t-xs); color: var(--texto-3); line-height: 1.4; margin: 2px 0 0; }

/* ---- Fase 26 (Pivote Vertical Belleza, "Site Builder como juego visual"):
   el Constructor de Sitio ("Sitio Web") dejaba cada sección como un <h3>
   suelto flotando en la página -- un formulario largo y plano, "sistema
   del 2010". Cada sección ahora vive en su propia tarjeta con ícono,
   título y borde: configurar la landing se siente como avanzar tarjeta
   por tarjeta (mismo lenguaje visual que el wizard de /registro), no como
   rellenar un examen de un solo tirón. ---- */
.tarjeta-config {
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--r-l);
  -webkit-backdrop-filter: var(--desenfoque); backdrop-filter: var(--desenfoque);
  padding: var(--e5) var(--e4); margin-top: var(--e4); box-shadow: var(--sombra-ultra-suave);
}
.tarjeta-config__cabecera { display: flex; align-items: flex-start; gap: var(--e3); }
.tarjeta-config__icono {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-m);
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--brand-color) 14%, var(--superficie-alta)); color: var(--brand-color);
}
.tarjeta-config__titulo { font-size: var(--t-m); font-weight: 700; margin: 0; }
.tarjeta-config__subtitulo { font-size: var(--t-xs); color: var(--texto-3); margin: 2px 0 0; line-height: 1.4; }
.tarjeta-config__cuerpo { margin-top: var(--e4); display: flex; flex-direction: column; gap: var(--e3); }

/* ---- Botón dinámico de Soporte en el menú "Más": estándar en Plan Básico,
   dorado/resaltado en Plan Pro -- una señal visible de que el plan pagado
   también compra un trato distinto. ---- */
.menu-mas__item.soporte-vip {
  background: linear-gradient(135deg, #FDE68A, #F59E0B);
  color: #4A2E03; font-weight: 800;
  box-shadow: 0 6px 18px rgba(245, 158, 11, .28);
}
.menu-mas__item.soporte-vip:active { transform: scale(.98); }

/* ---- Onboarding Tour Nativo (§1, "Guided Spotlight Tour"): overlay fijo +
   recorte visual del elemento activo + tooltip con navegación. El oscurecido
   real lo hace el box-shadow gigante del spotlight (truco clásico: evita
   clip-path y funciona con cualquier forma de contenedor), así que el propio
   .tour-overlay solo existe como capa raíz para el spotlight y el tooltip. ---- */
.tour-overlay { position: fixed; inset: 0; z-index: 200; }
/* Fase 21 (§4, "Warm Onboarding"): sin borde duro -- un anillo suave de
   dos capas (glow tenue + trazo fino translúcido) reemplaza el
   border:2px solid de antes, mismo lenguaje "sin bordes sólidos" del
   resto del rediseño. */
.tour-spotlight {
  position: fixed; z-index: 201;
  border-radius: var(--r-m);
  box-shadow:
    0 0 0 9999px rgba(9, 11, 15, .72),
    0 0 0 1.5px color-mix(in srgb, var(--brand-color) 70%, transparent),
    0 0 24px 4px color-mix(in srgb, var(--brand-color) 35%, transparent);
  pointer-events: none;
  transition: top 220ms cubic-bezier(.4, 0, .2, 1), left 220ms cubic-bezier(.4, 0, .2, 1),
              width 220ms cubic-bezier(.4, 0, .2, 1), height 220ms cubic-bezier(.4, 0, .2, 1);
}
@media (prefers-reduced-motion: reduce) { .tour-spotlight { transition: none; } }
.tour-tooltip {
  position: fixed; z-index: 202;
  width: min(320px, calc(100vw - 24px));
  background: color-mix(in srgb, var(--bg-dark) 92%, transparent);
  -webkit-backdrop-filter: var(--desenfoque-fuerte);
  backdrop-filter: var(--desenfoque-fuerte);
  border: 1px solid var(--borde);
  border-radius: var(--r-l);
  box-shadow: var(--sombra-flotante);
  padding: var(--e4);
  transition: top 180ms ease, left 180ms ease;
}
.tour-tooltip__cerrar {
  position: absolute; top: var(--e2); right: var(--e2);
  width: 28px; height: 28px; border: none; border-radius: var(--r-full);
  background: var(--superficie-alta); color: var(--texto-2); font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
.tour-tooltip__contador {
  font-size: 11px; font-weight: 800; color: var(--acento);
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: var(--e2);
}
.tour-tooltip__mensaje { font-size: var(--t-s); color: var(--texto); line-height: 1.55; margin: 0 var(--e5) var(--e4) 0; }
.tour-tooltip__acciones { display: flex; align-items: center; justify-content: flex-end; gap: var(--e3); }
.tour-tooltip__anterior { padding: 0 var(--e2); min-height: 40px; }
.tour-tooltip__siguiente { max-width: 140px; min-height: 40px; }

/* ---- Toast (Fase 21 §4, "Warm Onboarding"): reemplaza al único alert()
   que le quedaba al sistema de tours -- una píldora de cristal que aparece
   y se retira sola, nunca bloquea la interacción. ---- */
.tour-toast {
  position: fixed; left: 50%; bottom: calc(90px + var(--seguro-abajo)); z-index: 210;
  transform: translateX(-50%) translateY(8px);
  max-width: calc(100vw - var(--e5) * 2);
  background: color-mix(in srgb, var(--bg-dark) 92%, transparent);
  -webkit-backdrop-filter: var(--desenfoque-fuerte); backdrop-filter: var(--desenfoque-fuerte);
  border: 1px solid var(--borde); border-radius: var(--r-full);
  padding: var(--e3) var(--e5); font-size: var(--t-s); font-weight: 600; color: var(--texto);
  text-align: center; box-shadow: var(--sombra-flotante);
  opacity: 0; pointer-events: none;
  transition: opacity 220ms ease, transform 220ms ease;
}
.tour-toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) { .tour-toast { transition: none; } }
.galeria-admin-item__acciones .boton-icono { width: 28px; height: 28px; font-size: 12px; }

/* ==========================================================================
   FASE 20 (§3) — Motor de Reservas como Bottom Sheet (Plan Pro) o Premium
   Booking Widget centrado (Plan Básico / /reservar). Controlado desde
   #app[data-modo-sheet] y #app[data-plan-tipo] -- ver embudo.php.

   §Vitrina Viva: de este bloque desapareció el Bottom Nav de pestañas
   (Inicio/Galería/Reseñas). La hoja de reservas se queda -- que la reserva
   suba SOBRE la vitrina sin borrarla es buena UX --, pero fragmentar la
   landing en tres pestañas enterraba la galería, que es justo la sección
   que más vende en este vertical. Ahora todo se recorre con scroll.
   ========================================================================== */

/* El Bottom Sheet (z-index 56) taparía el CTA fijo (z-index 30, base) si
   compartieran capa -- en modo app el CTA debe verse SIEMPRE por encima,
   tanto en "Inicio" (Nav) como reservando (Continuar/Confirmar). */
#app[data-modo-sheet="1"] .accion-fija { z-index: 58; }

/* ---- Motor de reservas como Bottom Sheet (Plan Pro): el wrapper existe
   siempre en el DOM (ver embudo.php), pero solo se comporta como una hoja
   de cristal flotante bajo #app[data-modo-sheet="1"]. Sin ese atributo
   (Plan Básico / /reservar) es un <div> sin estilos propios: el widget de
   reservas queda como contenido normal de la página, a pantalla completa. ---- */
.motor-reservas-sheet { display: flex; flex-direction: column; flex: 1; }
.motor-reservas-sheet__agarre { display: none; }
.motor-reservas-fondo { display: none; }

#app[data-modo-sheet="1"] .motor-reservas-fondo {
  display: block; position: fixed; inset: 0; z-index: 55;
  background: rgba(0, 0, 0, .5);
}
#app[data-modo-sheet="1"] .motor-reservas-fondo[hidden] { display: none; }

#app[data-modo-sheet="1"] .motor-reservas-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 56;
  max-width: 480px; margin: 0 auto;
  height: min(92vh, 860px);
  background: color-mix(in srgb, var(--bg-dark) 94%, transparent);
  -webkit-backdrop-filter: var(--desenfoque-fuerte); backdrop-filter: var(--desenfoque-fuerte);
  border: 1px solid var(--borde); border-bottom: none;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--sombra-flotante);
  overflow-y: auto; overscroll-behavior: contain;
  transform: translateY(100%);
  transition: transform 320ms cubic-bezier(.4, 0, .2, 1);
}
#app[data-modo-sheet="1"] .motor-reservas-sheet.activo { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  #app[data-modo-sheet="1"] .motor-reservas-sheet { transition: none; }
}
#app[data-modo-sheet="1"] .motor-reservas-sheet__agarre {
  display: block; flex-shrink: 0;
  width: 40px; height: 4px; border-radius: var(--r-full);
  background: color-mix(in srgb, var(--brand-color) 35%, var(--borde));
  margin: var(--e3) auto var(--e1);
}

/* ---- Premium Booking Widget (Plan Básico / /reservar): sin Bottom Nav, el
   widget centrado verticalmente cuando el contenido cabe en la pantalla --
   UI limpia tipo Apple, la insignia de confianza reemplaza a la landing. ---- */
#app[data-modo-sheet="0"] .motor-reservas-sheet .pantalla { justify-content: center; }

/* ==========================================================================
   FASE 21 (§3) — Módulo de Control Financiero.
   ========================================================================== */
.fila-movimiento__icono {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--r-full);
}
.fila-movimiento__icono.ingreso { color: var(--exito); background: color-mix(in srgb, var(--exito) 14%, transparent); }
.fila-movimiento__icono.gasto { color: var(--peligro); background: color-mix(in srgb, var(--peligro) 12%, transparent); }
.fila-movimiento__monto { font-weight: 800; font-size: var(--t-s); white-space: nowrap; flex-shrink: 0; }
.fila-movimiento__monto.ingreso { color: var(--exito); }
.fila-movimiento__monto.gasto { color: var(--peligro); }

/* Login del panel: ayuda de acceso por WhatsApp (sin recuperación por correo) */
.login-soporte { margin-top: var(--e5); padding-top: var(--e4); border-top: 1px solid var(--borde); text-align: center; }
.login-soporte p { margin: 0 0 var(--e3); font-size: var(--t-s); color: var(--texto-2); }

/* ==========================================================================
   Autoservicio del cliente sobre su cita (/estado/{token}): cambiar o cancelar
   ========================================================================== */
.cambio-acciones { display: flex; flex-direction: column; gap: var(--e2); max-width: 320px; margin: var(--e4) auto 0; }
.cambio-cancelar { color: var(--peligro); }
.cambio-panel { width: 100%; min-width: 0; box-sizing: border-box; max-width: 420px; margin: var(--e4) auto 0; display: flex; flex-direction: column; gap: var(--e3); }
.cambio-panel > * { min-width: 0; max-width: 100%; }
.cambio-panel__titulo { margin: 0; font-size: var(--t-l); font-weight: 800; text-align: center; }
.cambio-dias, .cambio-horas { display: flex; gap: var(--e2); overflow-x: auto; padding-bottom: var(--e1); scroll-snap-type: x proximity; }
.cambio-horas { flex-wrap: wrap; overflow: visible; }
.cambio-chip {
  flex: 0 0 auto; min-height: var(--tap-min); padding: 0 var(--e4); border-radius: var(--r-m);
  border: 1px solid var(--borde); background: var(--superficie); color: var(--texto); font: inherit; font-weight: 600; cursor: pointer; scroll-snap-align: start;
}
.cambio-chip--dia { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; padding: var(--e2) var(--e3); min-width: 58px; font-size: var(--t-xs); }
.cambio-chip--dia strong { font-size: var(--t-l); line-height: 1.1; }
.cambio-chip.seleccionado { background: var(--primary-cta); color: var(--text-on-cta); border-color: transparent; }

/* Filas de configuración que son botones (p. ej. Equipo): alineadas como las demás listas */
button.fila-config { width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer; border: 0; }
.fila-config--inactiva { opacity: .6; }

/* Equipo: tarjetas de profesional en la landing pública */
.equipo-lista { display: grid; gap: 14px; margin-top: 16px; }
.equipo-tarjeta { display: flex; gap: 14px; padding: 14px; border: 1px solid var(--borde, rgba(127,127,127,.25)); border-radius: 14px; min-width: 0; }
.equipo-tarjeta__avatar { flex: 0 0 72px; width: 72px; height: 72px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; background: rgba(127,127,127,.18); font-weight: 700; font-size: 1.6rem; }
.equipo-tarjeta__avatar img { width: 100%; height: 100%; object-fit: cover; }
.equipo-tarjeta__cuerpo { min-width: 0; flex: 1; }
.equipo-tarjeta__nombre { margin: 0; font-size: 1.05rem; }
.equipo-tarjeta__meta { margin: 2px 0 6px; font-size: .85rem; opacity: .75; }
.equipo-tarjeta__desc { margin: 0 0 8px; font-size: .92rem; overflow-wrap: anywhere; }
.equipo-tarjeta__chips { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.equipo-tarjeta__chips li { font-size: .75rem; padding: 3px 9px; border-radius: 999px; background: rgba(127,127,127,.16); }
.equipo-tarjeta__acciones { display: flex; flex-wrap: wrap; gap: 8px; }
@media (min-width: 720px) { .equipo-lista { grid-template-columns: 1fr 1fr; } }

.portafolio-prof { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.portafolio-prof__foto { position: relative; aspect-ratio: 1; border-radius: 10px; overflow: hidden; }
.portafolio-prof__foto img { width: 100%; height: 100%; object-fit: cover; }
.portafolio-prof__foto .boton-icono { position: absolute; top: 4px; right: 4px; background: rgba(0,0,0,.6); color: #fff; }

/* Combo: "¿Quieres agregar algo más?" en el paso de fecha */
.combo-extras { margin-top: 18px; }
.combo-extras__titulo { margin: 0 0 8px; font-size: .9rem; opacity: .8; }
.combo-extras__lista { display: flex; flex-wrap: wrap; gap: 8px; }
.combo-chip { border: 1px solid var(--borde, rgba(127,127,127,.35)); background: transparent; color: inherit; padding: 8px 12px; border-radius: 999px; font: inherit; font-size: .85rem; cursor: pointer; }
.combo-chip.seleccionado { background: var(--acento, #c9a227); color: var(--acento-texto, #111); border-color: transparent; font-weight: 600; }
.combo-extras__total { margin: 10px 0 0; font-size: .88rem; font-weight: 600; }
.fila-config.seleccionada { outline: 2px solid var(--acento, #c9a227); }

/* Hoy: tarjeta "Ahora" */
.tarjeta-ahora { border: 1px solid var(--borde, rgba(127,127,127,.25)); border-radius: 14px; padding: 12px 14px; margin: 14px 0; }
.tarjeta-ahora__titulo { margin: 0 0 8px; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; opacity: .7; }
.ahora-fila { display: flex; align-items: center; gap: 10px; padding: 6px 0; min-width: 0; }
.ahora-fila__punto { flex: 0 0 10px; width: 10px; height: 10px; border-radius: 50%; background: #9aa0a6; }
.ahora-fila--libre .ahora-fila__punto { background: #2e9e5b; }
.ahora-fila--ocupado .ahora-fila__punto, .ahora-fila--en_servicio .ahora-fila__punto { background: #e0a100; }
.ahora-fila__texto { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: .85rem; overflow-wrap: anywhere; }
.ahora-fila .boton-texto { flex: 0 0 auto; white-space: nowrap; }
.chip-hora.seleccionado { outline: 2px solid var(--acento, #c9a227); }

/* Agenda: arrastrar y soltar una cita */
.agenda-cita { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.agenda-cita--arrastrando { z-index: 30; opacity: .92; box-shadow: 0 10px 26px rgba(0,0,0,.35); cursor: grabbing; transition: none; }
.agenda-arrastre-etiqueta { position: fixed; z-index: 1000; pointer-events: none; background: #111; color: #fff; padding: 5px 10px; border-radius: 8px; font-size: .8rem; font-weight: 600; white-space: nowrap; }

.confirmo-ok { text-align: center; font-weight: 600; margin: 0 0 12px; }

/* Semáforo de asistencia */
.semaforo { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; flex: 0 0 10px; vertical-align: middle; box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.semaforo--verde { background: #2e9e5b; }
.semaforo--amarillo { background: #e0a100; }
.semaforo--rojo { background: #d93a3a; }
.semaforo--gris { background: #9aa0a6; }

/* Modo ráfaga */
.rafaga-iniciar { width: 100%; margin-bottom: 14px; }
.rafaga { max-width: 520px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }
.rafaga__progreso { height: 6px; border-radius: 999px; background: rgba(127,127,127,.25); overflow: hidden; }
.rafaga__progreso span { display: block; height: 100%; background: var(--acento, #c9a227); transition: width .25s; }
.rafaga__cuenta { margin: 0; font-size: .8rem; opacity: .7; }
.rafaga__nombre { margin: 0; font-size: 1.3rem; }
.rafaga__texto { width: 100%; box-sizing: border-box; font: inherit; padding: 10px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; resize: vertical; }
.rafaga__enviar { padding: 18px; font-size: 1.05rem; }
.rafaga__secundarias { display: flex; justify-content: space-between; gap: 8px; }
.rafaga-fin { text-align: center; padding: 40px 16px; }
.rafaga-fin__emoji { font-size: 3rem; margin: 0; }

.wab-pasos { padding-left: 20px; font-size: .9rem; line-height: 1.5; }
.wab-texto { width: 100%; box-sizing: border-box; font: inherit; padding: 10px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; margin-bottom: 8px; }

/* Lista de espera */
.pildora-fecha--llena .pildora-fecha__punto { background: #d93a3a; }
.pildora-fecha--llena { opacity: .75; }
.lista-espera { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; text-align: left; }
.lista-espera__titulo { margin: 0; font-weight: 600; }
.lista-espera input, .lista-espera select { font: inherit; padding: 10px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; }

/* Caja: hoja de cobro */
.cobro-total { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 14px; border-radius: 12px; background: rgba(127,127,127,.14); margin: 12px 0; }
.cobro-total strong { font-size: 1.5rem; }
.cobro-falta { margin: 6px 0 10px; font-weight: 600; color: #d93a3a; }
.cobro-falta--ok { color: #2e9e5b; }
.cobro-linea { margin-bottom: 8px; }
.admin-sheet__accion.principal { font-weight: 700; border: 2px solid var(--acento, #c9a227); }

.caja-cierre { border: 1px solid var(--borde, rgba(127,127,127,.25)); border-radius: 14px; padding: 12px 14px; margin: 12px 0; }
.caja-cierre__titulo { margin: 0 0 6px; font-weight: 700; }

.fila-config--boton { width: 100%; text-align: left; cursor: pointer; font: inherit; color: inherit; }

/* Link propio de un profesional */
.banner-profesional { display: flex; align-items: center; gap: 12px; padding: 10px 16px; margin: 0 0 4px; border-bottom: 1px solid var(--borde, rgba(127,127,127,.25)); }
.banner-profesional__avatar { flex: 0 0 48px; width: 48px; height: 48px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; background: rgba(127,127,127,.18); font-weight: 700; }
.banner-profesional__avatar img { width: 100%; height: 100%; object-fit: cover; }
.banner-profesional__titulo { font-weight: 700; }
.banner-profesional__meta { font-size: .82rem; opacity: .75; }

/* Kit de redes */
.kit-link { display: flex; gap: 8px; }
.kit-link input { flex: 1; min-width: 0; font: inherit; padding: 10px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; }
.kit-vista { display: flex; justify-content: center; margin: 12px 0; }
.kit-vista canvas { max-width: 100%; height: auto; border-radius: 14px; box-shadow: 0 6px 24px rgba(0,0,0,.25); }
.kit-acciones { display: flex; flex-direction: column; gap: 8px; }

/* ---- Temas curados: estilo por nicho (html[data-estilo]) ---- */
html[data-estilo] :is(.vitrina-hero__titulo, .vitrina-seccion__titulo, .cierre-reserva__titulo, .pantalla__titulo, .encabezado__nombre, .equipo-tarjeta__nombre, .banner-profesional__titulo) {
  font-family: var(--fuente-titulo, var(--fuente));
  text-transform: var(--titulos-transform, none);
  letter-spacing: var(--titulos-spacing, normal);
  font-weight: var(--titulos-peso, 700);
  font-style: var(--titulos-estilo, normal);
}
html[data-estilo="barber-clasico"] { --r-s: 4px; --r-m: 6px; --r-l: 8px; --r-xl: 10px; --titulos-transform: uppercase; --titulos-spacing: .06em; --titulos-peso: 800; }
html[data-estilo="barber-urbano"]  { --r-s: 2px; --r-m: 4px; --r-l: 6px; --r-xl: 8px; --titulos-transform: uppercase; --titulos-spacing: .03em; --titulos-peso: 800; }
html[data-estilo="barber-vintage"] { --r-s: 6px; --r-m: 10px; --r-l: 14px; --r-xl: 18px; --fuente-titulo: Georgia, 'Times New Roman', serif; --titulos-peso: 700; --titulos-spacing: .01em; }
html[data-estilo="spa-suave"]      { --r-s: 14px; --r-m: 22px; --r-l: 30px; --r-xl: 38px; --fuente-titulo: Georgia, 'Times New Roman', serif; --titulos-peso: 500; }
html[data-estilo="glam"]           { --r-s: 12px; --r-m: 20px; --r-l: 28px; --r-xl: 36px; --fuente-titulo: Georgia, 'Times New Roman', serif; --titulos-peso: 600; --titulos-estilo: italic; }
html[data-estilo="glam"] .boton { border-radius: 999px; }
html[data-estilo^="barber"] .boton { border-radius: var(--r-s); }

/* Selector de temas en el panel */
.temas-listos { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin: 8px 0 16px; }
.tema-listo { position: relative; text-align: left; font: inherit; color: inherit; background: transparent; border: 1px solid var(--borde, rgba(127,127,127,.3)); border-radius: 14px; padding: 10px; cursor: pointer; display: flex; flex-direction: column; gap: 4px; }
.tema-listo--activo { outline: 2px solid var(--acento, #c9a227); }
.tema-listo__muestra { display: flex; height: 34px; border-radius: 8px; overflow: hidden; }
.tema-listo__muestra i { flex: 1; }
.tema-listo__muestra i:nth-child(1) { background: var(--t-primario); }
.tema-listo__muestra i:nth-child(2) { background: var(--t-secundario); }
.tema-listo__muestra i:nth-child(3) { background: var(--t-fondo); }
.tema-listo__nombre { font-weight: 700; font-size: .9rem; }
.tema-listo__desc { font-size: .75rem; opacity: .7; }
.tema-listo__etiqueta { position: absolute; top: 6px; right: 6px; font-size: .62rem; background: var(--acento, #c9a227); color: #111; padding: 2px 6px; border-radius: 999px; font-weight: 700; }

.ficha-aviso { margin: 6px 0 10px; padding: 8px 12px; border-radius: 10px; background: rgba(127,127,127,.14); font-size: .88rem; }
.ficha-aviso p { margin: 2px 0; overflow-wrap: anywhere; }
.ficha-aviso__alergia { color: #d93a3a; font-weight: 700; }
.cumple-campos { display: flex; gap: 8px; }
.cumple-campos select { flex: 1; font: inherit; padding: 10px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; }

/* Fidelidad en /estado */
.fidelidad { margin: 16px 0; padding: 12px 14px; border: 1px solid var(--borde, rgba(127,127,127,.25)); border-radius: 14px; font-size: .92rem; }
.fidelidad p { margin: 4px 0; }
.fidelidad__invita input { width: 100%; box-sizing: border-box; font: inherit; padding: 9px; border-radius: 10px; border: 1px solid rgba(127,127,127,.35); background: transparent; color: inherit; margin: 6px 0; }

/* ==========================================================================
   Fase 5A · VISÍTANOS — horario con «abierto ahora», cómo llegar y redes
   ========================================================================== */
.visitanos__tarjeta {
  margin-top: var(--e5);
  padding: var(--e5);
  border: 1px solid var(--borde); border-radius: var(--r-l);
  background: var(--superficie);
  display: flex; flex-direction: column; gap: var(--e4);
}
.visitanos__estado {
  display: inline-flex; align-items: center; gap: var(--e2); align-self: flex-start;
  padding: 6px 14px; border-radius: var(--r-full);
  font-size: var(--t-s); font-weight: 700;
  background: color-mix(in srgb, var(--peligro) 12%, transparent); color: var(--peligro);
}
.visitanos__estado--abierto { background: color-mix(in srgb, var(--exito) 14%, transparent); color: var(--exito); }
.visitanos__punto { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.visitanos__estado--abierto .visitanos__punto { animation: visitanos-latido 1.8s ease-in-out infinite; }
@keyframes visitanos-latido { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent); } 50% { box-shadow: 0 0 0 6px transparent; } }
@media (prefers-reduced-motion: reduce) { .visitanos__estado--abierto .visitanos__punto { animation: none; } }
.visitanos__horario { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.visitanos__horario li {
  display: flex; justify-content: space-between; gap: var(--e4);
  padding: var(--e3) 0; border-bottom: 1px dashed var(--borde);
  font-size: var(--t-s); color: var(--texto-2);
}
.visitanos__horario li:last-child { border-bottom: 0; }
.visitanos__horario li span:first-child { font-weight: 700; color: var(--texto); }
.visitanos__direccion { font-size: var(--t-s); color: var(--texto-2); line-height: 1.6; }
.visitanos__acciones { display: flex; flex-wrap: wrap; gap: var(--e2); }
.visitanos__acciones .boton { flex: 1 1 160px; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.visitanos__redes { display: flex; gap: var(--e2); }
.visitanos__red {
  width: 46px; height: 46px; border-radius: var(--r-full);
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--borde); background: var(--superficie-alta); color: var(--texto);
  transition: transform var(--transicion), border-color var(--transicion), color var(--transicion);
}
.visitanos__red:hover, .visitanos__red:focus-visible { transform: translateY(-2px); border-color: var(--acento); color: var(--acento); }

/* ==========================================================================
   Fase 5A · MI PÁGINA — asesor de marketing (panel del dueño)
   ========================================================================== */
.mp-heroe {
  display: flex; align-items: center; gap: var(--e5); flex-wrap: wrap;
  padding: var(--e5); border: 1px solid var(--borde); border-radius: var(--r-l); background: var(--superficie);
  margin-bottom: var(--e4);
}
.mp-anillo { position: relative; width: 120px; height: 120px; flex: none; }
.mp-anillo svg { transform: rotate(-90deg); }
.mp-anillo__fondo { fill: none; stroke: var(--borde); stroke-width: 10; }
.mp-anillo__valor { fill: none; stroke-width: 10; stroke-linecap: round; transition: stroke-dashoffset 900ms cubic-bezier(.2, .8, .2, 1); }
.mp-anillo__num { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; }
.mp-anillo__num strong { font-size: 34px; font-weight: 800; letter-spacing: -.03em; }
.mp-anillo__num span { font-size: var(--t-xs); color: var(--texto-3); margin-top: 4px; }
.mp-heroe__texto { flex: 1 1 220px; display: flex; flex-direction: column; gap: var(--e2); }
.mp-heroe__texto p { font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; margin: 0; }
.mp-nivel {
  align-self: flex-start; padding: 4px 12px; border-radius: var(--r-full);
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--c); background: color-mix(in srgb, var(--c) 14%, transparent);
}
.mp-heroe__botones { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e1); }
.mp-heroe__botones .boton { width: auto; padding: 0 var(--e5); text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.mp-titulo { margin: var(--e6) 0 var(--e2); font-size: var(--t-m); font-weight: 800; letter-spacing: -.01em; }
.mp-acciones { display: grid; gap: var(--e3); }
.mp-accion { padding: var(--e4); border: 1px solid var(--borde); border-left: 4px solid var(--acento); border-radius: var(--r-m); background: var(--superficie); display: flex; flex-direction: column; gap: var(--e2); }
.mp-accion__cab { display: flex; justify-content: space-between; gap: var(--e3); align-items: baseline; }
.mp-accion p { margin: 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.mp-accion .boton { align-self: flex-start; width: auto; padding: 0 var(--e4); }
.mp-pts { font-size: var(--t-xs); font-weight: 800; color: var(--texto-3); white-space: nowrap; }
.mp-accion .mp-pts { color: var(--exito); }
.mp-vista { display: flex; flex-direction: column; align-items: center; gap: var(--e4); }
.mp-telefono { width: 300px; max-width: 100%; padding: 12px; border-radius: 40px; background: #0b0d12; box-shadow: var(--sombra-flotante); }
.mp-telefono__pantalla { border-radius: 30px; overflow: hidden; background: #fff; aspect-ratio: 9 / 18.5; }
.mp-telefono iframe { width: 100%; height: 100%; border: 0; display: block; }
.mp-compartir { border: 1px solid var(--borde); border-radius: var(--r-m); overflow: hidden; background: var(--superficie); max-width: 460px; }
.mp-compartir img { width: 100%; aspect-ratio: 1200 / 630; object-fit: cover; display: block; }
.mp-compartir__vacia { aspect-ratio: 1200 / 630; display: flex; align-items: center; justify-content: center; text-align: center; padding: var(--e4); font-size: var(--t-s); color: var(--texto-3); background: var(--superficie-alta); }
.mp-compartir__texto { padding: var(--e3) var(--e4); display: flex; flex-direction: column; gap: 2px; }
.mp-compartir__texto small { text-transform: uppercase; letter-spacing: .06em; color: var(--texto-3); font-size: 11px; }
.mp-compartir__texto strong { font-size: var(--t-s); }
.mp-compartir__texto span { font-size: var(--t-xs); color: var(--texto-2); line-height: 1.45; }
.mp-textos { display: flex; flex-direction: column; gap: var(--e2); }
.mp-texto { display: flex; align-items: center; gap: var(--e3); padding: var(--e3) var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); }
.mp-texto > div { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mp-texto strong { font-size: var(--t-s); }
.mp-texto small { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--texto-3); }
.mp-texto span { font-size: var(--t-xs); color: var(--texto-2); line-height: 1.45; }
.mp-texto .boton { width: auto; padding: 0 var(--e4); min-height: 40px; }
.mp-cat { margin-bottom: var(--e5); }
.mp-cat__cab { display: flex; justify-content: space-between; align-items: baseline; }
.mp-cat__cab h3 { margin: 0; font-size: var(--t-s); text-transform: uppercase; letter-spacing: .08em; color: var(--texto-2); }
.mp-cat__cab span { font-size: var(--t-xs); font-weight: 800; color: var(--texto-3); }
.mp-barra { height: 6px; border-radius: 99px; background: var(--borde); margin: var(--e2) 0 var(--e3); overflow: hidden; }
.mp-barra i { display: block; height: 100%; border-radius: inherit; background: var(--acento); }
.mp-regla { border-bottom: 1px solid var(--borde); }
.mp-regla summary { display: flex; align-items: center; gap: var(--e3); min-height: 44px; cursor: pointer; list-style: none; font-size: var(--t-s); }
.mp-regla summary::-webkit-details-marker { display: none; }
.mp-regla__t { flex: 1; }
.mp-regla__t small { color: var(--texto-3); }
.mp-marca { width: 22px; text-align: center; font-weight: 800; }
.mp-regla--ok .mp-marca { color: var(--exito); }
.mp-regla--parcial .mp-marca { color: var(--alerta); }
.mp-regla--falta .mp-marca { color: var(--peligro); }
.mp-regla p { margin: 0 0 var(--e2) 34px; font-size: var(--t-xs); color: var(--texto-2); line-height: 1.6; }
.mp-regla .boton-texto { margin: 0 0 var(--e3) 34px; }
@media (prefers-reduced-motion: reduce) { .mp-anillo__valor { transition: none; } }

/* ==========================================================================
   Fase 5B · DISEÑO PRO — variantes de hero, antes/después, video, «más pedido»
   ========================================================================== */
/* --- Hero centrado: todo al centro, ideal para marcas de spa / vintage --- */
.vitrina-hero--centrado { justify-content: center; text-align: center; }
.vitrina-hero--centrado .vitrina-hero__contenido { align-items: center; }
.vitrina-hero--centrado .vitrina-hero__subtitulo { margin-inline: auto; }
.vitrina-hero--centrado .vitrina-hero__meta { justify-content: center; }
.vitrina-hero--centrado .vitrina-hero__logo { width: 92px; height: 92px; border-radius: 50%; }
.vitrina-hero--centrado .vitrina-hero__velo { background: linear-gradient(180deg, var(--velo-2) 0%, var(--velo-2) 50%, var(--velo-3) 100%); }

/* --- Hero dividido: la foto manda arriba, el mensaje respira abajo sobre el fondo de marca --- */
.vitrina-hero--dividido { min-height: 0; justify-content: flex-start; color: var(--texto); background: var(--fondo); }
.vitrina-hero--dividido .vitrina-hero__media { position: relative; inset: auto; z-index: 0; height: min(58svh, 460px); }
.vitrina-hero--dividido .vitrina-hero__velo {
  inset: auto 0 auto 0; top: 0; height: min(58svh, 460px);
  background: linear-gradient(180deg, rgba(0, 0, 0, .18) 0%, rgba(0, 0, 0, 0) 40%, var(--fondo) 100%);
}
.vitrina-hero--dividido .vitrina-hero__contenido { margin-top: calc(-1 * var(--e8)); padding-top: 0; padding-bottom: var(--e6); }
.vitrina-hero--dividido .vitrina-hero__titulo { color: var(--texto); text-shadow: none; }
.vitrina-hero--dividido .vitrina-hero__subtitulo { color: var(--texto-2); text-shadow: none; }
.vitrina-hero--dividido .sello-hero { background: var(--superficie-alta); border-color: var(--borde); color: var(--texto-2); }
.vitrina-hero--dividido .sello-hero strong { color: var(--texto); }
.vitrina-hero--dividido .boton-fantasma { color: var(--texto); border-color: var(--borde); }
.vitrina-hero--dividido .vitrina-hero__logo { border-color: var(--fondo); }

/* --- Antes / después --- */
.ad-lista { margin-top: var(--e5); display: flex; flex-direction: column; gap: var(--e5); }
.ad { margin: 0; }
.ad__lienzo { position: relative; aspect-ratio: 4 / 5; border-radius: var(--r-l); overflow: hidden; background: var(--superficie-alta); touch-action: pan-y; box-shadow: var(--sombra-suave); }
.ad__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ad__antes { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--p)) 0 0); }
.ad__asa { position: absolute; top: 0; bottom: 0; left: var(--p); width: 2px; margin-left: -1px; background: #fff; box-shadow: 0 0 12px rgba(0, 0, 0, .4); pointer-events: none; }
.ad__asa i { position: absolute; top: 50%; left: 50%; width: 42px; height: 42px; margin: -21px 0 0 -21px; border-radius: 50%; background: #fff; box-shadow: 0 4px 16px rgba(0, 0, 0, .35); }
.ad__asa i::before, .ad__asa i::after { content: ''; position: absolute; top: 50%; width: 0; height: 0; margin-top: -5px; border: 5px solid transparent; }
.ad__asa i::before { left: 8px; border-right-color: #111; border-left: 0; }
.ad__asa i::after { right: 8px; border-left-color: #111; border-right: 0; }
.ad__etiqueta { position: absolute; top: var(--e3); padding: 5px 12px; border-radius: var(--r-full); background: rgba(0, 0, 0, .55); color: #fff; font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; pointer-events: none; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.ad__etiqueta--antes { left: var(--e3); }
.ad__etiqueta--despues { right: var(--e3); }
.ad__rango { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; }
.ad__rango:focus-visible { opacity: 1; outline: 3px solid var(--acento); outline-offset: -3px; background: transparent; }
.ad__titulo { margin-top: var(--e2); font-size: var(--t-s); font-weight: 700; color: var(--texto-2); text-align: center; }

/* --- Video con portada propia --- */
.video-facade {
  position: relative; margin-top: var(--e5); aspect-ratio: 16 / 9; border-radius: var(--r-l); overflow: hidden;
  background: linear-gradient(155deg, var(--primario), color-mix(in srgb, var(--primario) 45%, var(--acento) 55%)) center / cover;
  box-shadow: var(--sombra);
}
.video-facade::before { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0, 0, 0, .15), rgba(0, 0, 0, .5)); }
.video-facade__play {
  position: absolute; top: 50%; left: 50%; width: 72px; height: 72px; margin: -36px 0 0 -36px; border-radius: 50%;
  border: 0; background: #fff; color: #111; display: flex; align-items: center; justify-content: center; padding-left: 4px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .4); cursor: pointer; transition: transform var(--transicion);
}
.video-facade__play:hover, .video-facade__play:focus-visible { transform: scale(1.08); }
.video-facade--activo::before { display: none; }
.video-facade iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* --- Sello «Más pedido» en las filas de la carta --- */
.carta-item__sello { flex: none; align-self: center; padding: 3px 9px; border-radius: var(--r-full); background: var(--acento); color: var(--text-on-cta); font-size: 9px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }

/* Fase 5B · panel: selector de estilo de portada y editor de antes/después */
.hero-opciones { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e2); margin-bottom: var(--e4); }
.hero-opcion { display: flex; flex-direction: column; gap: 4px; padding: var(--e2); border: 2px solid var(--borde); border-radius: var(--r-m); cursor: pointer; background: var(--superficie); }
.hero-opcion input { position: absolute; opacity: 0; pointer-events: none; }
.hero-opcion:has(input:checked) { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, transparent); }
.hero-opcion:has(input:focus-visible) { outline: 3px solid var(--acento); }
.hero-opcion strong { font-size: var(--t-s); }
.hero-opcion small { font-size: 11px; color: var(--texto-3); line-height: 1.35; }
.hero-opcion__mini { position: relative; display: block; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden; background: linear-gradient(160deg, #3b3b46, #15151a); }
.hero-opcion__mini b { position: absolute; left: 12%; height: 5px; border-radius: 3px; background: rgba(255, 255, 255, .85); }
.hero-opcion__mini b:nth-of-type(1) { bottom: 26%; width: 62%; }
.hero-opcion__mini b:nth-of-type(2) { bottom: 14%; width: 38%; background: var(--acento); }
.hero-opcion__mini--centrado b { left: 50%; transform: translateX(-50%); }
.hero-opcion__mini--centrado b:nth-of-type(1) { bottom: 50%; }
.hero-opcion__mini--centrado b:nth-of-type(2) { bottom: 40%; }
.hero-opcion__mini--dividido { background: linear-gradient(180deg, #3b3b46 0 55%, #f1f1f4 55% 100%); }
.hero-opcion__mini--dividido b { background: #222; }
.hero-opcion__mini--dividido b:nth-of-type(2) { background: var(--acento); }
.ad-admin-fila { display: flex; align-items: center; gap: var(--e2); padding: var(--e2) 0; border-bottom: 1px solid var(--borde); }
.ad-admin-fila img { width: 52px; height: 52px; object-fit: cover; border-radius: 8px; }
.ad-admin-fila__titulo { flex: 1; font-size: var(--t-s); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ad-nuevo { display: flex; flex-direction: column; gap: var(--e2); margin-top: var(--e3); }
.ad-nuevo__fotos { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e2); }
.ad-nuevo__foto { aspect-ratio: 4 / 5; border: 2px dashed var(--borde); border-radius: var(--r-m); display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--texto-3); font-weight: 700; overflow: hidden; }
.ad-nuevo__foto img { width: 100%; height: 100%; object-fit: cover; }

/* ==========================================================================
   Fase 5C · «Mi página»: pestañas, resultados, contenido y guía de Google
   ========================================================================== */
.mp-tabs { display: flex; gap: 4px; padding: 4px; margin: var(--e3) 0 var(--e4); border-radius: var(--r-full); background: var(--superficie-alta); position: sticky; top: 0; z-index: 3; }
.mp-tab { flex: 1; min-height: 40px; border: 0; border-radius: var(--r-full); background: transparent; font-weight: 700; font-size: var(--t-s); color: var(--texto-2); cursor: pointer; }
.mp-tab--activa { background: var(--fondo); color: var(--texto); box-shadow: var(--sombra-suave); }
.mp-periodo { display: flex; gap: var(--e2); margin-bottom: var(--e3); }
.mp-kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e2); }
.mp-kpi { display: flex; flex-direction: column; gap: 2px; padding: var(--e3) var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); }
.mp-kpi span { font-size: var(--t-xs); color: var(--texto-3); font-weight: 700; }
.mp-kpi strong { font-size: 28px; letter-spacing: -.03em; line-height: 1.1; }
.mp-kpi em { font-style: normal; font-size: 11px; color: var(--texto-2); }
.mp-delta { font-size: 11px; font-weight: 800; }
.mp-delta--sube { color: var(--exito); }
.mp-delta--baja { color: var(--peligro); }
.mp-barras { display: flex; align-items: flex-end; gap: 2px; height: 90px; padding: var(--e2); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); }
.mp-barras i { flex: 1; min-width: 2px; border-radius: 3px 3px 0 0; background: var(--acento); opacity: .85; }
.mp-fuentes { display: flex; flex-direction: column; gap: var(--e2); }
.mp-fuente { display: grid; grid-template-columns: 96px 1fr 36px; align-items: center; gap: var(--e3); font-size: var(--t-s); }
.mp-fuente .mp-barra { margin: 0; }
.mp-fuente strong { text-align: right; }
.mp-barra--grande { height: 10px; margin: var(--e3) 0 var(--e2); }
.mp-dias { display: flex; flex-direction: column; gap: var(--e3); }
.mp-dia { padding: var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); display: flex; flex-direction: column; gap: var(--e2); }
.mp-dia header { display: flex; justify-content: space-between; align-items: center; }
.mp-dia h4 { margin: 0; font-size: var(--t-m); }
.mp-dia p { margin: 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.mp-dia textarea { width: 100%; border: 1px solid var(--borde); border-radius: var(--r-s); background: var(--fondo); color: var(--texto); padding: var(--e3); font: inherit; font-size: var(--t-s); resize: vertical; }
.mp-dia .boton { align-self: flex-start; width: auto; padding: 0 var(--e4); }
.mp-formato { padding: 3px 10px; border-radius: var(--r-full); background: color-mix(in srgb, var(--acento) 16%, transparent); font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.mp-paso { border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); margin-bottom: var(--e2); padding: 0 var(--e4); }
.mp-paso summary { display: flex; align-items: center; gap: var(--e3); min-height: 52px; cursor: pointer; list-style: none; font-weight: 700; }
.mp-paso summary::-webkit-details-marker { display: none; }
.mp-paso[open] { padding-bottom: var(--e4); }
.mp-paso p { margin: 0 0 var(--e2); font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.mp-paso--hecho .mp-marca { color: var(--exito); }
.mp-paso .mp-marca { width: 26px; height: 26px; line-height: 26px; border-radius: 50%; background: var(--superficie-alta); font-size: var(--t-xs); }
.mp-valor { margin: 0 0 var(--e2); padding: var(--e3); border-radius: var(--r-s); background: var(--fondo); border: 1px dashed var(--borde); white-space: pre-wrap; word-break: break-word; font: inherit; font-size: var(--t-s); }
.mp-check { display: flex; align-items: center; gap: var(--e2); margin-top: var(--e3); font-size: var(--t-s); font-weight: 700; min-height: 44px; }

/* ==========================================================================
   Fase 6A · «Qué hacer hoy» y resumen de la semana
   ========================================================================== */
.acciones-titulo { margin: var(--e4) 0 var(--e2); font-size: var(--t-s); text-transform: uppercase; letter-spacing: .08em; color: var(--texto-2); }
.accion-tarjeta { display: flex; gap: var(--e3); padding: var(--e4); margin-bottom: var(--e2); border: 1px solid var(--borde); border-left: 4px solid var(--acento); border-radius: var(--r-m); background: var(--superficie); transition: opacity 200ms, transform 200ms; }
.accion-tarjeta--sale { opacity: 0; transform: translateX(24px); }
.accion-tarjeta__icono { flex: none; width: 40px; height: 40px; border-radius: var(--r-s); display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--acento) 16%, transparent); }
.accion-tarjeta__cuerpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.accion-tarjeta__cuerpo p { margin: 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.5; }
.accion-tarjeta__botones { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e1) var(--e3); margin-top: var(--e2); }
.accion-tarjeta__botones .boton { width: auto; min-height: 40px; padding: 0 var(--e4); }
.accion-tarjeta__botones .boton-texto { font-size: var(--t-xs); color: var(--texto-3); }
.resumen-semana { margin: var(--e3) 0; border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); }
.resumen-semana summary { display: flex; align-items: center; gap: var(--e3); min-height: 52px; padding: 0 var(--e4); cursor: pointer; list-style: none; }
.resumen-semana summary::-webkit-details-marker { display: none; }
.resumen-semana summary > span:first-child { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--texto-3); font-weight: 800; }
.resumen-semana summary strong { font-size: var(--t-l); letter-spacing: -.02em; }
.resumen-semana__cuerpo { padding: 0 var(--e4) var(--e4); }
.resumen-semana__cuerpo ul { margin: 0 0 var(--e3); padding-left: 18px; font-size: var(--t-s); color: var(--texto-2); line-height: 1.7; }
.resumen-semana__cuerpo .boton { width: auto; padding: 0 var(--e4); }

/* Fase 6A · Super Admin: salud del SaaS */
.sa-embudo { display: flex; flex-direction: column; gap: var(--e2); margin: var(--e3) 0 var(--e5); }
.sa-embudo__fila { display: grid; grid-template-columns: 170px 1fr 90px; align-items: center; gap: var(--e3); font-size: var(--t-s); }
.sa-embudo__barra { height: 10px; border-radius: 99px; background: var(--borde); overflow: hidden; }
.sa-embudo__barra i { display: block; height: 100%; border-radius: inherit; background: var(--acento); }
.sa-embudo__fila strong { text-align: right; font-variant-numeric: tabular-nums; }
.sa-estados { display: flex; flex-wrap: wrap; gap: var(--e2); margin: var(--e3) 0 var(--e5); }
.sa-estado-chip { padding: 6px 14px; border-radius: var(--r-full); background: var(--superficie-alta); font-size: var(--t-s); }
.sa-estado-chip--activo strong { color: var(--exito); }
.sa-estado-chip--en_riesgo strong { color: var(--peligro); }
.sa-estado-chip--dormido strong { color: var(--alerta); }
@media (max-width: 560px) { .sa-embudo__fila { grid-template-columns: 1fr 1fr; } .sa-embudo__barra { grid-column: 1 / -1; order: 3; } }

/* Planes: precio anterior tachado y lista de lo que incluye */
.factura-plan__precio-antes { font-size: var(--t-m); color: var(--texto-3); text-decoration: line-through; text-decoration-thickness: 2px; margin-right: var(--e1); }
.factura-plan__incluye { list-style: none; margin: 0 0 var(--e3); padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: var(--t-s); color: var(--texto-2); }
.factura-plan__incluye li::before { content: '✓'; color: var(--exito); font-weight: 800; margin-right: 8px; }

/* Planes: candado en el menú «Más» y hoja «Mejora tu plan» */
.menu-mas__item--bloqueado { opacity: .72; }
.menu-mas__candado { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: var(--r-full); background: color-mix(in srgb, var(--acento) 18%, transparent); font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.mejora-plan__texto { margin: 0 0 var(--e3); font-size: var(--t-m); line-height: 1.55; color: var(--texto-2); }
.mejora-plan__nivel { margin: 0 0 var(--e4); font-size: var(--t-s); color: var(--texto-2); }
.mejora-plan__insignia { padding: 3px 10px; border-radius: var(--r-full); background: var(--acento); color: var(--text-on-cta); font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; margin-right: 6px; }

/* Asistente de IA */
.ia-cuota { padding: var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); display: flex; flex-direction: column; gap: var(--e2); margin-bottom: var(--e4); }
.ia-cuota strong { font-size: 22px; letter-spacing: -.02em; }
.ia-cuota small { color: var(--texto-3); }
.ia-tareas { display: grid; gap: var(--e2); margin-bottom: var(--e4); }
.ia-tarea { display: grid; grid-template-columns: 40px 1fr; column-gap: var(--e3); text-align: left; padding: var(--e3) var(--e4); border: 2px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); cursor: pointer; color: inherit; }
.ia-tarea:disabled { opacity: .5; cursor: not-allowed; }
.ia-tarea__icono { grid-row: 1 / 3; width: 40px; height: 40px; border-radius: var(--r-s); display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--acento) 16%, transparent); }
.ia-tarea small { color: var(--texto-2); font-size: var(--t-xs); line-height: 1.45; }
.ia-tarea--activa { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, transparent); }
.ia-form { padding: var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); margin-bottom: var(--e4); }
.ia-form select, .ia-form input, .ia-form textarea { width: 100%; }
.ia-estrategia { padding: var(--e4); border-radius: var(--r-m); background: color-mix(in srgb, var(--acento) 10%, transparent); margin-bottom: var(--e3); }
.ia-estrategia p { margin: 4px 0 0; font-size: var(--t-s); line-height: 1.55; }
.ia-estrategia ul { margin: 6px 0 0; padding-left: 18px; font-size: var(--t-s); line-height: 1.6; }
.ia-dia { padding: var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); margin-bottom: var(--e3); display: flex; flex-direction: column; gap: var(--e2); }
.ia-dia header { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }
.ia-dia header small { margin-left: auto; color: var(--texto-3); }
.ia-dia h4 { margin: 0; font-size: var(--t-m); }
.ia-dia__porque { margin: 0; font-size: var(--t-xs); color: var(--texto-3); }
.ia-dia details p { margin: 6px 0 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.ia-bloque { border: 1px dashed var(--borde); border-radius: var(--r-s); padding: var(--e3); background: var(--fondo); margin-bottom: var(--e2); }
.ia-bloque__cab { display: flex; align-items: center; gap: var(--e2); font-size: var(--t-xs); }
.ia-bloque__cab small { color: var(--texto-3); }
.ia-bloque__cab .boton-texto { margin-left: auto; }
.ia-bloque__texto { margin: var(--e2) 0 0; white-space: pre-wrap; font-size: var(--t-s); line-height: 1.55; }
.ia-escenas { list-style: none; padding: 0; margin: 0 0 var(--e3); display: flex; flex-direction: column; gap: var(--e2); }
.ia-escenas li { display: grid; grid-template-columns: 64px 1fr; gap: 2px var(--e3); padding: var(--e3); border: 1px solid var(--borde); border-radius: var(--r-s); font-size: var(--t-s); }
.ia-escenas small { color: var(--acento); font-weight: 800; }
.ia-escenas em { grid-column: 2; color: var(--texto-3); font-size: var(--t-xs); font-style: normal; }
.ia-racha { color: var(--acento); font-weight: 700; }
.ia-misiones { display: grid; gap: var(--e2); margin-bottom: var(--e4); }
.ia-mision { display: flex; flex-direction: column; align-items: stretch; gap: var(--e3); padding: var(--e4); border: 2px solid var(--acento); border-radius: var(--r-m); background: color-mix(in srgb, var(--acento) 7%, transparent); }
.ia-mision p { margin: 4px 0 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.5; }
.ia-ideas { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e2); }
.ia-ideas .sa-chip.ia-idea--activa { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 14%, transparent); font-weight: 700; }
.ia-dia--hecho { opacity: .72; border-color: var(--exito); }
.ia-dia__objetivo { margin: 0; font-size: var(--t-s); font-weight: 600; }
.ia-dia__quees { margin: 0; font-size: var(--t-s); color: var(--texto-2); line-height: 1.55; }
.ia-dia details > summary { cursor: pointer; font-weight: 700; font-size: var(--t-s); padding: 4px 0; }
.ia-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ia-chips small { color: var(--texto-3); }
.ia-chips span { padding: 2px 10px; border-radius: var(--r-full); border: 1px solid var(--borde); font-size: var(--t-xs); }
.ia-pasos { margin: var(--e2) 0 0; padding-left: 22px; display: flex; flex-direction: column; gap: var(--e2); font-size: var(--t-s); line-height: 1.55; }
.ia-pasos li strong { display: block; }
.ia-pasos li span { color: var(--texto-2); }
.ia-nota { padding: var(--e3); border-radius: var(--r-s); background: var(--fondo); border: 1px solid var(--borde); margin-top: var(--e2); font-size: var(--t-s); }
.ia-nota p { margin: 4px 0 0; line-height: 1.5; }
.ia-nota ul { margin: 4px 0 0; padding-left: 18px; line-height: 1.55; }
.ia-hecho { margin-top: var(--e2); }
.ia-usados { margin: var(--e3) 0 0; color: var(--texto-3); }
.ia-paso-campana { padding: var(--e4); border: 1px solid var(--borde); border-radius: var(--r-m); background: var(--superficie); margin-bottom: var(--e3); }
.ia-paso-campana h4 { margin: 0 0 var(--e2); }
.ia-semana { margin-bottom: var(--e4); }
.ia-semana h4 { margin: 0 0 var(--e2); }
.ia-semana__pieza { display: flex; align-items: center; gap: var(--e3); padding: var(--e3); border: 1px solid var(--borde); border-radius: var(--r-s); background: var(--superficie); margin-bottom: var(--e2); }
.ia-semana__pieza > div { flex: 1; }
.ia-semana__pieza p { margin: 2px 0; font-size: var(--t-s); }
.ia-semana__pieza small { color: var(--texto-3); }
.ia-academia { display: flex; flex-direction: column; gap: var(--e2); margin-bottom: var(--e5); }
.ia-academia details { border: 1px solid var(--borde); border-radius: var(--r-s); padding: var(--e3) var(--e4); background: var(--superficie); }
.ia-academia summary { cursor: pointer; font-weight: 700; }
.ia-academia summary small { color: var(--texto-3); font-weight: 400; margin-left: 6px; }
.ia-academia ul { margin: var(--e2) 0 0; padding-left: 18px; font-size: var(--t-s); line-height: 1.6; color: var(--texto-2); }
.sa-ia-prueba { list-style: none; margin: 0 0 var(--e5); padding: 0; display: flex; flex-direction: column; gap: var(--e2); font-size: var(--t-s); }
.sa-ia-prueba li { padding: var(--e3) var(--e4); border-radius: var(--r-s); border: 1px solid var(--borde); line-height: 1.5; }
.sa-ia-prueba li.ok { border-color: var(--exito); }
.sa-ia-prueba li.mal { border-color: var(--peligro); }

/* Super Admin → Enlaces */
.sa-enlaces { display: grid; gap: var(--e4); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.sa-enlace { padding: var(--e4); display: flex; flex-direction: column; gap: var(--e3); }
.sa-enlace__titulo { font-weight: 700; }
.sa-enlace__ayuda { margin: 0; color: var(--texto-3); font-size: var(--t-s); line-height: 1.5; }
.sa-enlace__url, .sa-enlace__mensaje { width: 100%; font: inherit; font-size: var(--t-s); padding: var(--e3); border-radius: var(--r-s); border: 1px solid var(--borde); background: transparent; color: inherit; }
.sa-enlace__mensaje { resize: vertical; line-height: 1.5; }
.sa-enlace__acciones { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e2); }
.sa-enlace__origenes { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e3); }
.sa-chip { padding: var(--e2) var(--e4); border-radius: 999px; border: 1px solid var(--borde); background: transparent; color: inherit; font: inherit; font-size: var(--t-s); cursor: pointer; }
.sa-chip.activo { border-color: var(--acento, currentColor); font-weight: 700; }

/* ---- Fila virtual (panel) ---- */
.fv-barra { display: flex; flex-direction: column; gap: var(--e3); padding: var(--e4); border-radius: var(--r-m); border: 1px solid var(--borde); margin-bottom: var(--e4); }
.fv-interruptor { display: flex; align-items: center; gap: var(--e3); cursor: pointer; }
.fv-interruptor input { position: absolute; opacity: 0; }
.fv-interruptor span { position: relative; width: 48px; height: 28px; border-radius: 999px; background: var(--borde); transition: background .2s; flex: none; }
.fv-interruptor span::after { content: ''; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; transition: transform .2s; }
.fv-interruptor input:checked + span { background: var(--exito); }
.fv-interruptor input:checked + span::after { transform: translateX(20px); }
.fv-interruptor input:focus-visible + span { outline: 2px solid var(--acento); outline-offset: 2px; }
.fv-enlace { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e2); }
.fv-enlace code { flex: 1 1 100%; word-break: break-all; font-size: var(--t-s); color: var(--texto-2); }
.fv-btn { padding: 9px 14px; font-size: var(--t-s); min-height: 0; }
.fv-resumen { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--e2); margin-bottom: var(--e4); }
.fv-resumen > div { padding: var(--e3); border-radius: var(--r-m); background: var(--superficie); text-align: center; }
.fv-resumen strong { display: block; font-size: var(--t-l); font-variant-numeric: tabular-nums; }
.fv-resumen small { color: var(--texto-3); font-size: 11.5px; }
.fv-agregar, .fv-cerrados { margin-bottom: var(--e4); }
.fv-agregar summary, .fv-cerrados summary { cursor: pointer; font-weight: 600; padding: var(--e3) 0; }
.fv-form { display: flex; flex-direction: column; gap: var(--e3); padding: var(--e3) 0; }
.fv-turno { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e3); padding: var(--e3) var(--e4); border-radius: var(--r-m); border: 1px solid var(--borde); margin-bottom: var(--e2); }
.fv-turno__num { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: var(--superficie-alta); font-weight: 800; font-size: var(--t-l); font-variant-numeric: tabular-nums; flex: none; }
.fv-turno__info { flex: 1; min-width: 140px; }
.fv-turno__info small { display: block; color: var(--texto-3); }
.fv-turno__acciones { display: flex; flex-wrap: wrap; gap: var(--e2); width: 100%; }
.fv-turno--llamado { border-color: var(--alerta); }
.fv-turno--atendiendo { border-color: var(--exito); }
.fv-turno--ausente, .fv-turno--cancelado { opacity: .7; }
@media (min-width: 640px) { .fv-turno__acciones { width: auto; } }

/* ---- Varias sedes ---- */
.admin-sede { display: flex; align-items: center; justify-content: center; gap: var(--e2); width: 100%; padding: var(--e2) var(--e4); border: 0; border-top: 1px solid var(--borde); background: var(--superficie); color: var(--texto); font: inherit; font-size: var(--t-s); font-weight: 600; cursor: pointer; }
.admin-sede[hidden] { display: none; }
.sd-lista { display: flex; flex-direction: column; gap: var(--e2); padding: var(--e3) 0; }
.sd-opcion { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: var(--e3) var(--e4); border-radius: var(--r-m); border: 1px solid var(--borde); background: transparent; color: var(--texto); font: inherit; text-align: left; cursor: pointer; }
.sd-opcion small { color: var(--texto-3); }
.sd-opcion span { color: var(--exito); font-size: var(--t-s); font-weight: 600; }
.sd-opcion--activa { border-color: var(--acento); }
.sd-totales { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e2); margin-bottom: var(--e4); }
.sd-totales > div { padding: var(--e3) var(--e4); border-radius: var(--r-m); background: var(--superficie); }
.sd-totales small, .sd-cifras small { display: block; color: var(--texto-3); font-size: 11.5px; }
.sd-totales strong { font-size: var(--t-l); font-variant-numeric: tabular-nums; }
.sd-sede { padding: var(--e4); border-radius: var(--r-m); border: 1px solid var(--borde); margin-bottom: var(--e3); }
.sd-sede--activa { border-color: var(--acento); }
.sd-sede header { display: flex; align-items: center; justify-content: space-between; gap: var(--e3); margin-bottom: var(--e3); }
.sd-sede header small { display: block; color: var(--texto-3); }
.sd-aqui { color: var(--exito); font-size: var(--t-s); font-weight: 600; }
.sd-cifras { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e2); margin-bottom: var(--e2); }
.sd-cifras b { font-variant-numeric: tabular-nums; }
.sd-ia { margin: var(--e4) 0; color: var(--texto-2); font-size: var(--t-s); }
@media (min-width: 640px) { .sd-totales { grid-template-columns: repeat(4, 1fr); } .sd-cifras { grid-template-columns: repeat(4, 1fr); } }

.sa-ia-precios { padding: var(--e4); display: flex; flex-direction: column; gap: var(--e3); margin-bottom: var(--e5); }
.sa-ia-precios__fila { display: flex; flex-wrap: wrap; align-items: end; gap: var(--e3); }
.sa-ia-precios__fila > strong { flex: 1 1 100%; }
.sa-ia-precios__fila label { display: flex; flex-direction: column; gap: 4px; font-size: var(--t-xs); color: var(--texto-3); flex: 1 1 140px; }
.sa-ia-precios__fila input { font: inherit; padding: var(--e2) var(--e3); border-radius: var(--r-s); border: 1px solid var(--borde); background: transparent; color: var(--texto); }
.ia-marca { border: 1px solid var(--borde); border-radius: var(--r-m); padding: var(--e3) var(--e4); background: var(--superficie); margin-bottom: var(--e4); }
.ia-marca summary { cursor: pointer; font-weight: 700; }
.ia-marca form { margin-top: var(--e3); display: flex; flex-direction: column; gap: var(--e3); }
.ia-marca input, .ia-marca select, .ia-marca textarea { width: 100%; }
.ia-refinar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: var(--e2); }
.ia-refinar small { color: var(--texto-3); width: 100%; }
.ia-refinar .sa-chip { padding: 4px 12px; font-size: var(--t-xs); }
.ia-refinar .sa-chip:disabled { opacity: .5; cursor: wait; }
#sa-ia-mes { font: inherit; padding: var(--e2) var(--e3); border-radius: var(--r-s); border: 1px solid var(--borde); background: transparent; color: inherit; color-scheme: dark light; }
.sa-ia-precios select { font: inherit; padding: var(--e2) var(--e3); margin-left: var(--e2); border-radius: var(--r-s); border: 1px solid var(--borde); background: transparent; color: inherit; }
.avisos-ok { color: var(--exito); margin: 0 0 var(--e3); line-height: 1.5; }
.avisos-mal { margin: 0 0 var(--e3); line-height: 1.5; padding: var(--e3); border-radius: var(--r-s); border: 1px solid var(--alerta); background: color-mix(in srgb, var(--alerta) 10%, transparent); }
.avisos-lista { list-style: none; padding: 0; margin: var(--e3) 0 0; display: flex; flex-direction: column; gap: var(--e2); font-size: var(--t-s); }
.avisos-lista li { padding: var(--e3); border-radius: var(--r-s); border: 1px solid var(--borde); line-height: 1.5; }
.avisos-lista li.ok { border-color: var(--exito); }
.avisos-lista li.mal { border-color: var(--peligro); }
.avisos-guia { margin-top: var(--e3); font-size: var(--t-s); }
.avisos-guia summary { cursor: pointer; font-weight: 700; }
.avisos-guia ol { padding-left: 20px; line-height: 1.6; color: var(--texto-2); }
.aviso-servicio { display: block; width: 100%; text-align: left; margin-top: var(--e2); padding: var(--e2) var(--e3); border-radius: var(--r-s); border: 1px solid var(--alerta); background: color-mix(in srgb, var(--alerta) 10%, transparent); color: inherit; font: inherit; font-size: var(--t-xs); line-height: 1.4; cursor: pointer; }
.check-lista { display: flex; flex-direction: column; gap: var(--e2); }
.check-lista .check-politica { display: flex; align-items: center; gap: var(--e3); margin: 0; }
.check-lista .check-politica input { flex-shrink: 0; width: 20px; height: 20px; }
.check-lista .check-politica span { font-size: var(--t-s); }
