/* app.css — MODO.GYM member app (white-label).
   Calibrated to iPhone 14 Pro Max: 430x932 logical pt (@3x). 1 CSS px == 1 iOS pt here,
   so every size below is the literal on-device point value read off the screenshots. */

:root{
  --header:#25261f;        /* dark charcoal top bar (Oráculo) */
  --ink:#101114;           /* headings / primary text */
  --text:#2b2b2d;
  --muted:#8c8c91;
  --muted-2:#a9a9ae;
  --border:#ececed;
  --btn-gray:#d8d8db;      /* "View membership plan" / "Browse classes" buttons */
  --btn-gray-ink:#141416;
  --pill-dark:#1b1c1e;     /* floating barcode pill */
  /* texto e iconos SOBRE la barra oscura. Estaba clavado como #fff en media docena de reglas, por
     eso el "Text color" de Website Integration no movía nada mas que el header y el footer. */
  --on-header:#ffffff;
  /* ── EL COLOR DEL PORTAL WEB ────────────────────────────────────────────────────────────
     Los pone applyLook desde Website Integration (bg / text / highlight) y las derivadas las
     calcula él, para que nadie tenga que elegir siete colores en el CRM. Aquí van los valores
     por omisión: con ellos el portal se ve EXACTAMENTE como hoy, así que un gym que no haya
     configurado nada no nota ningún cambio. */
  --pt-bg:#ffffff;        /* el fondo de la página */
  --pt-card:#ffffff;      /* la superficie de las tarjetas */
  --pt-line:#ececed;      /* líneas y bordes */
  --pt-ink:#101114;       /* el texto */
  --pt-muted:#6b6b73;     /* el texto secundario */
  --pt-hl:#101114;        /* lo seleccionado y los botones */
  --pt-hl-ink:#ffffff;    /* lo que se lee ENCIMA del highlight */
  --seg-off:#45463f;       /* inactive segment circle on the dark header */
  --seg-off-ink:#c4c4bd;
  --seg-on:#edede8;        /* active segment circle */
  --seg-on-ink:#25261f;
  --star-on:#f2b705;
  --nav-h:66px;
  --hdr-extra-h:91px;      /* alto del área extra del header — IGUAL en Timetable/Memberships/Bookings */
  --shadow-card:0 1px 3px rgba(20,20,30,.08);
  --statusbar:54px;        /* Dynamic Island / status-bar clear space */
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  font-family:'Rubik',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  color:var(--text);background:#fff;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}

/* --- FULL-BLEED en teléfono (nativo/PWA): sin topes de tamaño, sin marco. Los topes 430x932
       eran del preview de escritorio y en un iPhone 16 Pro Max (440x956) dejaban franjas grises
       a los lados y abajo. El marco de "teléfono" ahora vive SÓLO en la media query de escritorio. --- */
.device{
  width:100%;height:100vh;height:100dvh;margin:0 auto;
  background:#fff;position:relative;overflow:hidden;
  display:flex;flex-direction:column;
}
/* App NATIVA (Capacitor). Mínimo a propósito: `.device` ya trae 100dvh y funciona; forzar
   height:100% + position:fixed en el body rompía el layout en la app de staff (la barra inferior
   quedaba fuera de vista). Aquí sólo se frena el rebote del DOCUMENTO — el del contenido lo hace
   .view con overscroll-behavior:contain, que es el que sí queremos que rebote como liga. */
html.cap, html.cap body{ background:#fff; overscroll-behavior:none; }
html.cap .device{ max-width:none;max-height:none;margin:0;border-radius:0;box-shadow:none; }

/* ============ ESCRITORIO: portal web de verdad, no un teléfono dibujado ============
   Antes, arriba de 480px se pintaba un marco de iPhone de 430px centrado sobre fondo gris. Servía
   como preview mientras la app era sólo móvil, pero como PORTAL PÚBLICO es lo que hace ver anticuado
   a Glofox: quien evalúa el gimnasio desde su laptop ve una app de juguete en medio de la pantalla.

   La misma app se ensancha:
     · sin marco ni fondo gris — ocupa la ventana
     · la barra inferior de tabs sube y se vuelve navegación superior (en escritorio nadie tiene el
       pulgar abajo, y una barra pegada al piso de un monitor de 27" queda a medio metro del ojo)
     · el contenido vive en una columna con tope de ancho: una línea de texto de 1400px no se lee
     · las listas de tarjetas pasan a rejilla de 2–3 columnas (ver .grid-auto abajo)
   En móvil NADA cambia: todo esto vive dentro de la media query. */
@media (min-width:900px){
  body{background:#fff}
  .device{max-width:none;max-height:none;border-radius:0;box-shadow:none;height:100vh;height:100dvh}

  /* la barra de tabs pasa arriba, junto al header */
  .device{display:flex;flex-direction:column}
  .bottomnav{
    order:-1;position:relative;height:auto;padding:0 24px;
    display:flex;justify-content:center;gap:6px;
    border-top:none;border-bottom:1px solid rgba(255,255,255,.10);
  }
  .bottomnav button{
    flex:0 0 auto;flex-direction:row;gap:9px;padding:14px 18px;font-size:14px;
    border-radius:0;position:relative;
  }
  .bottomnav button span{font-size:14px}
  .bottomnav button svg{width:19px;height:19px}
  .bn-account{
    display:flex;flex-direction:row;align-items:center;gap:9px;
    margin-left:auto;padding:14px 18px;font-size:14px;border:none;background:none;
    color:inherit;cursor:pointer;font-family:inherit;border-radius:0;
  }
  .bn-account span{font-size:14px;font-weight:600}
  .bn-account svg{width:19px;height:19px;opacity:.85}
  .bn-account:hover{opacity:.75}
  /* El FONDO de la barra va a todo lo ancho y lo que se centra es su CONTENIDO, con padding. Con
     max-width se encogía la barra entera y quedaban dos franjas blancas a los lados de una barra
     oscura — se veía como si la página estuviera mal cargada. */
  .bottomnav{justify-content:flex-start;padding:0 max(24px,calc((100% - 1120px)/2))}

  /* subrayado en la activa: en escritorio el color solo no basta para señalar dónde estás */
  .bottomnav button.active::after{
    content:"";position:absolute;left:14px;right:14px;bottom:0;height:3px;border-radius:3px 3px 0 0;background:var(--seg-on);
  }

  /* columna de lectura. El padding lateral lo pone cada vista; aquí sólo se acota el ancho. */
  .view > *{max-width:1120px;margin-left:auto;margin-right:auto}
  .topbar .tb-bar{max-width:1120px;margin:0 auto;height:64px}
  /* la tira de fechas y cualquier extra del header van a la MISMA columna: sueltos a todo lo ancho,
     los 7 días quedaban a 200px uno de otro y se leían como columnas de una tabla, no como una tira */
  .topbar .tb-extra > *{max-width:1120px;margin-left:auto;margin-right:auto}
  /* el check-in (Barcode/QR) es de socio: un visitante no tiene qué escanear */
  .floating{max-width:1120px;left:0;right:0;margin:0 auto}
  .tb-title{font-size:24px}

  /* Listas de tarjetas → rejilla. Se marcan con .grid-auto desde cada vista en vez de adivinar
     selectores: una regla que le pegue a "todo div dentro de .view" rompe layouts que ya funcionan. */
  .grid-auto{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px;align-items:start}
  /* …MENOS el horario. Una clase por tarjeta de 320px se lee como un catálogo de productos; lo que
     la gente hace aquí es RECORRER el día buscando su hora, y para eso una fila ancha —con la hora
     a un lado y el botón al otro— se barre con la vista mucho más rápido. Es lo que hace Glofox y
     en esto tienen razón. */
  .tt-list.grid-auto{display:block}

  /* las pantallas apiladas (detalle de clase, carrito) dejan de venir de la orilla: en una ventana
     ancha, deslizar 1400px se ve como un tirón. Aparecen con un fundido corto. */
  .screen{transform:none;opacity:0;transition:opacity .16s ease}
  .screen.show{transform:none;opacity:1}
  .screen.fromleft{transform:none}

  /* ── EL PORTAL SE VE COMO WEB, NO COMO LA APP ESTIRADA ──────────────────────────────────────
     Federico: "la tratas de hacer como la app de celular en vez de darle look and feel de web app".
     Tenía razón: aunque desde hace tiempo el portal ya ocupa la ventana y acota el ancho, seguía
     teniendo CHROME DE APP — barra oscura arriba e iconos de pestaña—, y eso es lo que delata que
     estás viendo un teléfono agrandado en vez de la página de un gimnasio.

     SÓLO html:not(.cap) Y SÓLO AQUÍ DENTRO: con sesión mandan los códigos de la app (quien ya entrena
     aquí viene a SU horario, no a una página de ventas), y en el teléfono no cambia ni un pixel.
     Los dos candados son a propósito. */
  html:not(.cap) body,html:not(.cap) .device{background:var(--pt-bg)}
  html:not(.cap) .bottomnav{
    background:var(--pt-bg);border-bottom:1px solid var(--pt-line);
    padding:0 max(24px,calc((100% - 1120px)/2));
  }
  /* FUERA LOS ICONOS. Un icono por pestaña es lenguaje de app: en una web se leen las palabras. */
  html:not(.cap) .bottomnav button svg{display:none}
  html:not(.cap) .bottomnav button{color:var(--pt-muted);font-size:15px;font-weight:500;padding:20px 0;margin-right:30px}
  html:not(.cap) .bottomnav button.active{color:var(--pt-ink);font-weight:600}
  html:not(.cap) .bottomnav button.active::after{left:0;right:0;background:var(--pt-hl);height:2px}
  /* "Log in" a la derecha, como enlace y no como pestaña */
  html:not(.cap) .bn-account{color:var(--pt-ink);font-size:15px;font-weight:600;padding:20px 0}
  html:not(.cap) .bn-account svg{display:none}
  html:not(.cap) .bn-logout{
    flex:none;display:flex;align-items:center;gap:7px;background:none;border:none;cursor:pointer;
    font-family:inherit;font-size:15px;font-weight:500;color:var(--pt-muted);padding:20px 0;margin-left:26px;
  }
  html:not(.cap) .bn-logout svg{display:none}
  html:not(.cap) .bn-logout:hover{color:var(--pt-ink)}

  /* La cabecera deja de ser una barra de app: mismo papel blanco, el nombre del gimnasio como
     TÍTULO de la página. La franja oscura a todo lo ancho era lo que más gritaba "esto es una app". */
  html:not(.cap) .topbar{background:var(--pt-bg);color:var(--pt-ink);padding-top:0;border-bottom:1px solid var(--pt-line)}
  html:not(.cap) .topbar .tb-bar{height:auto;padding-top:30px;padding-bottom:6px;justify-content:flex-start}
  html:not(.cap) .tb-title{font-size:34px;font-weight:700;letter-spacing:-.02em;color:var(--pt-ink);text-align:left}
  html:not(.cap) .tb-title.sm{font-size:34px}
  html:not(.cap) .topbar svg{color:var(--pt-muted)}
  /* la acción de la derecha del header (Filters) baja de tono: en web no compite con el título */
  html:not(.cap) .tb-right{color:var(--pt-muted);font-weight:500}

  /* Tipografía de lectura: en una página se lee más grande y más suelto que en una app. */
  html:not(.cap) .view{font-size:15px}
  /* Las tarjetas de clase y sus textos también siguen el color del portal. Traían #fff y
     var(--ink) fijos: sobre un fondo negro eso son tarjetas blancas flotando. */
  html:not(.cap) .pt-card{background:var(--pt-card);border-color:var(--pt-line)}
  html:not(.cap) .pt-name{color:var(--pt-ink)}
  html:not(.cap) .pt-when,html:not(.cap) .pt-meta{color:var(--pt-muted)}
  html:not(.cap) .pt-meta b{color:var(--pt-ink)}
  html:not(.cap) .pt-book{background:var(--pt-hl);color:var(--pt-hl-ink)}
  /* el semáforo, con los tonos que applyLook eligió según qué tan oscuro sea el fondo */
  html:not(.cap) .pt-pill{background:var(--pt-ok-bg,rgba(34,192,125,.14));color:var(--pt-ok-ink,#12805c)}
  html:not(.cap) .pt-pill.full{background:var(--pt-full-bg,rgba(239,74,90,.14));color:var(--pt-full-ink,#c0392b)}
  html:not(.cap) .pt-legend{color:var(--pt-muted)}
  /* ── EL RESTO DEL HORARIO ─────────────────────────────────────────────────────────────────
     La cabecera de List ("Tuesday 13" + el rango) y la de Week traían var(--ink): sobre un portal
     negro, negro sobre negro. Federico lo vio antes que yo y mi barrido NO lo habia cazado por una
     razón concreta: cuando lo corrí, el visitante no tenía clases, así que esa cabecera ni se
     pintaba. El barrido sólo ve lo que está en pantalla — por eso ahora se listan las reglas y se
     cubren TODAS las del horario, en vez de ir cazando la que se alcanza a ver. */
  html:not(.cap) .lv-cur{color:var(--pt-ink)}
  html:not(.cap) .lv-day{color:var(--pt-muted)}
  html:not(.cap) .lv-range{color:var(--pt-muted)}
  html:not(.cap) .lv-range:hover{color:var(--pt-ink);background:var(--pt-card)}
  html:not(.cap) .wk-range{color:var(--pt-ink)}
  html:not(.cap) .wk-arrow{color:var(--pt-muted)}
  html:not(.cap) .wk-arrow:hover{color:var(--pt-ink);background:var(--pt-card)}
  html:not(.cap) .wk-daylbl{background:var(--pt-card);border-color:var(--pt-line)}
  html:not(.cap) .wk-daylbl span{color:var(--pt-ink)}
  html:not(.cap) .pt-book[disabled],html:not(.cap) .wk-book[disabled]{color:var(--pt-muted);opacity:.6}
  html:not(.cap) .pt-pill.booked{background:var(--pt-card);color:var(--pt-muted)}
  html:not(.cap) .wk-card{background:var(--pt-card);border-color:var(--pt-line)}
  html:not(.cap) .wk-c-name,html:not(.cap) .wk-c-meta,html:not(.cap) .wk-book{color:var(--pt-ink)}
  html:not(.cap) .wk-c-when{color:var(--pt-muted)}
  html:not(.cap) .pt-day,html:not(.cap) .pt-legend,html:not(.cap) .wk-daylabel{color:var(--pt-muted)}
  /* .view trae background:#fff desde que la app era sólo móvil. Sin esto el fondo del gym pinta
     la barra y la cabecera y el CUERPO se queda blanco — con el texto ya en blanco encima, o sea
     invisible. Es peor que no haber pintado nada. */
  html:not(.cap) .view{color:var(--pt-ink);background:var(--pt-bg)}
  /* El estado vacío ("No classes scheduled") traía el color del header, que sobre un portal del
     MISMO color queda a 1.38 de contraste: invisible. Lo encontré barriendo la página entera en
     busca de texto ilegible, no leyendo reglas — era el único que quedaba. */
  html:not(.cap) .empty,html:not(.cap) .empty h3,html:not(.cap) .empty p{color:var(--pt-muted)}
  html:not(.cap) .empty svg{color:var(--pt-muted);opacity:.7}
  /* Barcode/QR es para enseñar en la puerta: en una laptop no hay nada que escanear. Ya estaba
     oculta para visitantes; en el portal web lo está para todos. */
  html:not(.cap) .floating{display:none}

  /* ── LAS HOJAS DEJAN DE SER PANTALLAS COMPLETAS ───────────────────────────────────────────
     Federico: "book se ve igual, como una app grandota". Tenía razón: Review booking es una hoja
     que sube desde abajo y ocupa la ventana entera, con la barra del botón de lado a lado. En un
     teléfono eso es lo correcto; en una laptop es la app estirada otra vez.
     En web se vuelven TARJETA CENTRADA sobre el fondo oscurecido, como las de Glofox. */
  html:not(.cap) .rb-overlay{align-items:center;justify-content:center;padding:28px;
    background:rgba(10,10,14,.58)}
  html:not(.cap) .rb-sheet{width:min(560px,100%);height:auto;max-height:86vh;border-radius:14px;
    transform:translateY(14px) scale(.99)}
  html:not(.cap) .rb-overlay.show .rb-sheet{transform:none}
  /* el botón deja de ser una franja de lado a lado y se queda dentro de la tarjeta */
  html:not(.cap) .rb-book{height:56px;border-radius:10px}

  /* LA FICHA DE LA CLASE, igual. `:has` decide por el contenido para no tocar las demás pantallas
     apiladas; si un navegador no lo entiende, se queda a pantalla completa como hoy. */
  html:not(.cap) .screen:has(> .cd){background:rgba(10,10,14,.58);display:flex;
    align-items:center;justify-content:center;padding:28px}
  html:not(.cap) .screen:has(> .cd) > .cd{position:relative;inset:auto;
    width:min(560px,100%);max-height:88vh;border-radius:14px;overflow:hidden}
  /* La foto baja de 44vh a una altura fija: a 44vh de una laptop se come media tarjeta y empuja
     todo lo demás fuera. Es lo que hacía falta para que QUEPA sin scrollear. */
  html:not(.cap) .screen:has(> .cd) .cd-hero{height:200px;min-height:0}
  html:not(.cap) .screen:has(> .cd) .cd-sheet{margin-top:0;border-radius:0;padding:20px 22px 22px}

  /* REVIEW PURCHASE, el mismo formato que Review booking — lo pidió Federico. Es la misma
     operación (revisar y confirmar), así que no hay razón para que se vean distintas: una se
     siente una tarjeta y la otra una pantalla completa. */
  html:not(.cap) .screen:has(> .rp){background:rgba(10,10,14,.58);display:flex;
    align-items:center;justify-content:center;padding:28px}
  html:not(.cap) .screen:has(> .rp) > .rp{position:relative;inset:auto;
    width:min(560px,100%);max-height:88vh;border-radius:14px;overflow:hidden}
  html:not(.cap) .screen:has(> .rp) .rp-top{padding-top:18px}
  html:not(.cap) .screen:has(> .rp) .rp-close{top:14px}
  html:not(.cap) .screen:has(> .rp) .rp-purchase{height:56px;border-radius:10px}

  /* ── LA TARJETA SE INVIERTE AL PASARLE ENCIMA ─────────────────────────────────────────────
     Lo pidió Federico: "que se pinte del color contrario, si está blanco en negro". En una
     rejilla de treinta celdas blancas no hay forma de saber cuál estás a punto de tocar — la
     sombrita que había no alcanza a 1400px de ancho. Invertir el color entero no deja duda.

     SÓLO EN WEB Y SÓLO CON MOUSE (hover:hover): en una pantalla táctil el hover se queda PEGADO
     después de tocar, así que la celda se quedaría negra hasta que toques otra. Y se incluye
     :focus-within para quien navega con el teclado, que si no se pierde igual.

     El Book ya no necesita aparecer: sobre negro se lee solo. */
  /* El texto se funde AL MISMO TIEMPO que el fondo. Sin esto el color cambia al instante y el
     fondo tarda 140ms: durante ese rato el texto es blanco sobre blanco, o sea ilegible. Se ve
     como un parpadeo y es de las cosas que no se saben explicar pero se sienten mal. */
  html:not(.cap) .wk-c-name,html:not(.cap) .wk-c-when,html:not(.cap) .wk-c-meta,
  html:not(.cap) .wk-book,html:not(.cap) .pt-name,html:not(.cap) .pt-when,
  html:not(.cap) .pt-meta{transition:color .14s}

  @media (hover:hover){
    html:not(.cap) .wk-card:hover,
    html:not(.cap) .wk-card:focus-within,
    html:not(.cap) .pt-card:hover,
    html:not(.cap) .pt-card:focus-within{
      background:var(--pt-hl);border-color:var(--pt-hl);
    }
    html:not(.cap) .wk-card:hover .wk-c-name,  html:not(.cap) .wk-card:focus-within .wk-c-name,
    html:not(.cap) .wk-card:hover .wk-c-meta,  html:not(.cap) .wk-card:focus-within .wk-c-meta,
    html:not(.cap) .wk-card:hover .wk-book,    html:not(.cap) .wk-card:focus-within .wk-book,
    html:not(.cap) .pt-card:hover .pt-name,    html:not(.cap) .pt-card:focus-within .pt-name,
    html:not(.cap) .pt-card:hover .pt-meta b,  html:not(.cap) .pt-card:focus-within .pt-meta b{
      color:var(--pt-hl-ink);
    }
    /* ⚠️ EL TEXTO SECUNDARIO TAMBIÉN SE INVIERTE. Aquí decía `opacity:.75` y era un error mío:
       la opacidad no cambia el COLOR, así que el texto apagado del portal —blanco al 62% sobre
       fondo negro— se quedaba blanco encima de una tarjeta ya blanca. O sea invisible: con el
       highlight en #FFFFFF, al pasar el mouse desaparecían la hora, el coach y la sala.
       Tiene que tomar el color que contrasta con el HIGHLIGHT, igual que el título, nada más que
       un poco más apagado. */
    html:not(.cap) .wk-card:hover .wk-c-when,  html:not(.cap) .wk-card:focus-within .wk-c-when,
    html:not(.cap) .pt-card:hover .pt-when,    html:not(.cap) .pt-card:focus-within .pt-when,
    html:not(.cap) .pt-card:hover .pt-meta,    html:not(.cap) .pt-card:focus-within .pt-meta{
      color:var(--pt-hl-ink);opacity:.74;
    }
    /* el botón de reservar se invierte también: sobre negro, blanco sólido */
    html:not(.cap) .pt-card:hover .pt-book,    html:not(.cap) .pt-card:focus-within .pt-book{
      background:var(--pt-hl-ink);color:var(--pt-hl);
    }
    /* la píldora de estado y el punto conservan SU color: son el semáforo de la clase y perderlo
       sería cambiar información por decoración */
  }

  /* ── MEMBERSHIPS A DOS COLUMNAS ────────────────────────────────────────────────────────────
     Izquierda el grupo (nombre y de qué va), derecha sus planes con el precio a la vista. Es el
     layout de una página de precios, no el de una app: quien evalúa un gimnasio desde su laptop
     viene a COMPARAR, y cada clic de más es alguien que se va. */
  html:not(.cap) .mb-group{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:48px;align-items:start;
    padding:44px 0;border-bottom:1px solid var(--pt-line);
  }
  html:not(.cap) .mb-count{display:none}          /* "3 Plans" sobra cuando los tres están a la vista */
  html:not(.cap) .mb-name{grid-column:1;font-size:30px;line-height:1.15;text-transform:uppercase;letter-spacing:-.01em;margin:0 0 14px;color:var(--pt-ink)}
  html:not(.cap) .mb-desc{grid-column:1;font-size:15px;line-height:1.6;color:var(--pt-muted);margin:0}
  html:not(.cap) .mb-view{display:none}           /* el botón era para esconder lo que aquí ya se ve */
  html:not(.cap) .mb-plans{
    display:block;grid-column:2;grid-row:1 / span 3;
    border:1px solid var(--pt-line);border-radius:14px;overflow:hidden;
  }
  html:not(.cap) .mb-plan{
    display:flex;align-items:center;gap:20px;padding:18px 20px;border-bottom:1px solid var(--pt-line);
  }
  html:not(.cap) .mb-plan:last-child{border-bottom:none}
  html:not(.cap) .mb-plan-txt{flex:1;min-width:0}
  html:not(.cap) .mb-plan-name{font-size:16px;font-weight:700;color:var(--pt-ink);text-transform:uppercase;letter-spacing:.02em}
  /* en itálica y en gris, como la referencia: es el detalle, no el titular */
  html:not(.cap) .mb-plan-meta{font-size:14px;font-style:italic;color:var(--pt-muted);margin-top:4px}
  html:not(.cap) .mb-buy{
    flex:none;border:1px solid var(--pt-hl);border-radius:999px;background:transparent;cursor:pointer;
    font-family:inherit;font-size:14px;font-weight:600;color:var(--pt-ink);padding:10px 22px;
  }
  html:not(.cap) .mb-buy:hover{background:var(--pt-hl);color:var(--pt-hl-ink)}
  /* "Your plan" se queda, pero sin la caja de app */
  html:not(.cap) .mb-group.mine{border:none;border-bottom:1px solid var(--pt-line);border-radius:0;background:none;padding:44px 0}
  html:not(.cap) .mb-mine{grid-column:1}

  /* Tablet: una columna, pero los planes siguen a la vista. */
  @media (max-width:1040px){
    html:not(.cap) .mb-group,html:not(.cap) .mb-group.mine{grid-template-columns:1fr;gap:22px}
    html:not(.cap) .mb-plans{grid-column:1;grid-row:auto}
  }
}

/* Pantallas intermedias (tablet, ventana a medias): sin marco tampoco, pero la navegación se queda
   abajo — a esa altura el aparato todavía se sostiene con las manos. */
@media (min-width:480px) and (max-width:899px){
  body{background:#fff}
  .device{max-width:none;max-height:none;border-radius:0;box-shadow:none}
}

/* ============ DARK TOP BAR ============ */
.topbar{
  flex:none;background:var(--header);color:var(--on-header);
  padding-top:max(env(safe-area-inset-top,0px), var(--statusbar));
  position:relative;z-index:2;   /* el contenido pasa POR DEBAJO al scrollear (ver .view) */
}
/* Rejilla de 3 columnas y NO un centrado con posiciones absolutas: el nombre del gimnasio es
   white-label y puede ser cualquier cosa. Con el título centrado a ojo sobre todo el ancho, un
   nombre largo se mete DEBAJO de la bolita del avatar y se le come la primera letra. Con grid, la
   columna del centro es lo que sobra entre avatar y acción, así que no hay forma de que choquen. */
.tb-bar{
  position:relative;display:grid;align-items:center;
  /* Las columnas de los LADOS miden igual (1fr cada una), así el título queda centrado en la
     PANTALLA y no entre el avatar y la acción. Con `44px … auto` el título se centraba en el
     hueco que quedaba: en Timetable casi no se notaba porque "Filters" compensaba, pero en Store,
     Community y Memberships —que no llevan acción a la derecha— se recorría ~27px a la derecha. */
  grid-template-columns:1fr minmax(0,auto) 1fr;
  column-gap:10px;height:52px;padding:0 16px;
}
.tb-avatar{
  grid-column:1;justify-self:start;
  /* ancla del badge rojo. Antes no hacía falta porque el avatar era `absolute` (y un absolute ya es
     referencia para sus hijos); al pasarlo a celda de grid quedó `static` y el badge se fue a la
     esquina de .tb-bar, encima de "Filters". */
  position:relative;
  width:44px;height:44px;border-radius:50%;
  background:#3b3c34 center/cover no-repeat;border:2px solid #54554b;
  display:flex;align-items:center;justify-content:center;
  color:#dcdcd4;font-weight:700;font-size:14px;
}
.tb-title{
  /* sin max-width: la columna del grid YA lo limita. Un porcentaje aquí era un tope calculado a ojo
     que no sabía cuánto miden el avatar ni la acción de la derecha. */
  grid-column:2;margin:0;font-size:28px;font-weight:700;color:var(--on-header);letter-spacing:.002em;
  text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;
}
.tb-title.sm{font-size:21px}
.tb-right{
  grid-column:3;justify-self:end;
  display:flex;align-items:center;gap:7px;background:none;border:none;cursor:pointer;
  color:#ececea;font-family:inherit;font-size:16px;font-weight:600;padding:6px 2px;
}
.tb-extra:empty{display:none}

/* --- segment tabs inside the dark header (Memberships / Bookings) ---
   La altura del área extra del header es la MISMA en las 3 pestañas (Timetable manda):
   --hdr-extra-h la fija tanto aquí como en .daystrip, así el header nunca "brinca" al cambiar de tab. */
.segrow{display:flex;justify-content:space-evenly;align-items:center;height:var(--hdr-extra-h);padding:0 18px;gap:14px}
.segrow.two{padding:0;gap:0}
.segrow.two .seg{width:50%}
.segrow.two .seg-lbl{white-space:nowrap}
.seg{
  background:none;border:none;cursor:pointer;font-family:inherit;
  display:flex;flex-direction:column;align-items:center;gap:8px;width:120px;
}
/* Bolitas ligeramente más chicas para acercarse a Glofox (eran 54/16). El icono de dentro se
   escala con la bolita desde el JS que la pinta, así que aquí sólo se ajusta la caja. */
.seg-ic{
  width:47px;height:47px;border-radius:50%;background:var(--seg-off);color:var(--seg-off-ink);
  display:flex;align-items:center;justify-content:center;
}
.seg-lbl{font-size:15px;font-weight:700;color:#b6b6b0;letter-spacing:.005em}
.seg.sel .seg-ic{background:var(--seg-on);color:var(--seg-on-ink)}
.seg.sel .seg-lbl{color:var(--on-header)}

/* --- day strip (Timetable): pinned "Today" + sliding 6-day window + calendar --- */
/* height = --hdr-extra-h: es exactamente su alto natural (2 + [50 num + 6 gap + 17 wd] + 16),
   así que no cambia nada visual — sólo lo FIJA para que Memberships/Bookings midan igual. */
.daystrip{display:flex;align-items:flex-start;height:var(--hdr-extra-h);padding:2px 8px 16px;gap:0;overflow:hidden}
.day{
  flex:none;background:none;border:none;cursor:pointer;font-family:inherit;
  display:flex;flex-direction:column;align-items:center;gap:6px;
}
.day-today{width:52px}
/* carril de días: SCROLL LIBRE (se queda donde lo dejes; tocar un día es lo que selecciona/centra) */
.daynums-vp{
  flex:1;min-width:0;overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
}
.daynums-vp::-webkit-scrollbar{display:none}
.daynums-track{display:flex}
.daynums-track .day{width:var(--cellw,52px);flex:none}
.day-cal{width:44px;color:#cfcfc9;justify-content:center;height:52px;margin-left:4px}
.day .num{
  font-size:22px;font-weight:700;color:var(--on-header);width:50px;height:50px;
  display:flex;align-items:center;justify-content:center;border-radius:50%;letter-spacing:-.01em;
}
/* la bolita de Today va un poco más abajo que los números (queda "asentada" en la fila) */
.day .num.today{font-size:15px;font-weight:600;margin-top:6px}
/* el nombre del día usa el mismo tono apagado que los días no elegidos, para que "Text color" lo
   mueva junto con todo lo demás en vez de quedarse en un gris fijo */
.day .wd{font-size:14px;font-weight:500;color:var(--seg-off-ink)}
/* EL DÍA ELEGIDO (y la bolita de Today) toman el HIGHLIGHT. Estaban en un gris clavado, por eso
   cambiar el color en Website Integration no movía nada aquí — que es justo donde se nota. */
.day.sel .num{background:var(--seg-on);color:var(--seg-on-ink)}

/* ============ SCROLL BODY + BOTTOM NAV ============ */
/* z-index:0 + el z-index:2 del header y del nav: el contenido tiene que pasar POR DEBAJO de los dos.
   `will-change:transform` (lo necesita el pull-to-refresh) promueve .view a su propia capa, y como
   .topbar/.bottomnav eran `static` sin z-index, el blanco se pintaba ENCIMA de ambos al scrollear. */
.view{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;background:#fff;
  will-change:transform;position:relative;z-index:0;
  /* el rebote se queda DENTRO de .view y no se propaga al documento (que arrastraría toda la app) */
  overscroll-behavior:contain}
/* Sólo en el HORARIO (la clase la pone y la quita la shell en cada cambio de pestaña): declara que
   este elemento panea SÓLO en vertical, así el arrastre HORIZONTAL le queda a la app y podemos
   cambiar de día con el dedo. Sin esto iOS se lo queda antes de que nuestros touchmove existan.
   Es lo mismo que ya hace `.bk-pager` para su swipe entre Bookings / Past / Waitlist. */
.view.tt-view{touch-action:pan-y}

/* ── El cambio de día se SIENTE ────────────────────────────────────────────────────────────────
   La lista entra DEL LADO al que vas: avanzas un día y entra por la derecha, retrocedes y entra
   por la izquierda. Es lo que convierte el repintado en un movimiento con sentido en vez de un
   parpadeo — un fade a secas se lee como "se recargó algo", no como "me moví".
   150ms a propósito: por encima de ~200 deja de sentirse instantáneo y empieza a estorbar.
   El desplazamiento es de 14px, no de media pantalla: se percibe sin que haya que esperarlo. */
@keyframes tt-in-next{ from{ opacity:0; transform:translate3d(14px,0,0) } to{ opacity:1; transform:none } }
@keyframes tt-in-prev{ from{ opacity:0; transform:translate3d(-14px,0,0) } to{ opacity:1; transform:none } }
.tt-in-next{animation:tt-in-next .15s cubic-bezier(.2,.7,.3,1) both}
.tt-in-prev{animation:tt-in-prev .15s cubic-bezier(.2,.7,.3,1) both}
/* Quien pidió menos movimiento en su iPhone no quiere que se lo devolvamos aquí. `both` deja el
   estado final aplicado aunque la animación no corra, así que la lista NUNCA se queda invisible. */
@media (prefers-reduced-motion: reduce){
  .tt-in-next,.tt-in-prev{animation-duration:.01ms}
}

/* --- pull-to-refresh: vive DETRÁS de .view (que se desliza hacia abajo y lo descubre) --- */
.ptr{
  position:absolute;left:0;right:0;height:56px;z-index:0;
  display:flex;align-items:center;justify-content:center;
  opacity:0;pointer-events:none;
}
.ptr-ring{
  width:26px;height:26px;border-radius:50%;
  border:2.5px solid var(--border);border-top-color:#8c8c91;
}
.ptr.on .ptr-ring{border-top-color:var(--ink)}
.ptr.busy .ptr-ring{animation:ptrSpin .7s linear infinite;border-top-color:var(--ink)}
@keyframes ptrSpin{to{transform:rotate(360deg)}}

.bottomnav{
  flex:none;display:flex;background:var(--header);
  border-top:1px solid rgba(255,255,255,.07);
  position:relative;z-index:2;   /* el contenido pasa POR DEBAJO al scrollear (ver .view) */
  padding:11px 0 max(env(safe-area-inset-bottom,0px), 16px);
}
.bottomnav button{
  flex:1;background:none;border:none;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:6px;
  color:#8d8d88;font-family:inherit;font-size:12px;font-weight:500;
}
/* Blanco FIJO, no `var(--on-header)`: esa variable la repinta el gym desde Website Integration, y
   si elige un tono oscuro la pestaña activa se vuelve ilegible sobre la barra oscura. El resto del
   header puede cambiar de color; la pestaña en la que estás, no. */
.bottomnav button.active{color:#fff;font-weight:600}
/* Al presionar SUBE el brillo, no baja. iOS pinta encima su propio gris de toque y eso era lo que
   apagaba la letra justo al tocarla; se quita y se pone una respuesta propia — la misma idea de
   Glofox: el botón se aclara un poco, no se apaga. */
.bottomnav button{-webkit-tap-highlight-color:transparent}
.bottomnav button:active{filter:brightness(1.45)}
.bottomnav button svg{display:block}

/* ============ FLOATING PILL (Barcode) ============ */
/* Cuenta en la barra. En TELÉFONO no se ve: ahí el avatar del header ya hace ese trabajo y una
   sexta pestaña apretaría a las otras cinco. Aparece sólo en escritorio, empujado a la derecha. */
.bn-account{display:none}

/* La X para salir del login. Sin ella, un visitante que toca "Log in" en el portal queda encerrado:
   el login reemplaza la app entera y no hay botón de regreso. */
.lg-close{
  position:absolute;top:max(14px,env(safe-area-inset-top,0px));right:14px;z-index:5;
  width:38px;height:38px;border-radius:50%;border:none;cursor:pointer;
  background:rgba(20,20,22,.06);color:#4a4a50;
  display:flex;align-items:center;justify-content:center;transition:.16s;
}
.lg-close:hover{background:rgba(20,20,22,.12);color:#111}

/* El check-in (Barcode/QR) es la credencial del socio: a un visitante sin cuenta no le sirve de
   nada y le estorba. Va fuera de toda media query — aplica igual en teléfono que en escritorio. */
.is-guest .floating{display:none}
/* La bolita "ME" con su globito rojo es la del SOCIO: su foto, sus documentos pendientes. A un
   visitante sin cuenta le enseña una identidad que no tiene y un pendiente que no es suyo — y como
   el portal ya trae el logo del gimnasio arriba, tampoco hace falta para saber dónde está. */
.is-guest .tb-avatar{display:none}
.floating{
  position:absolute;left:0;right:0;bottom:calc(var(--nav-h) + 26px + env(safe-area-inset-bottom,0px));
  display:flex;justify-content:center;pointer-events:none;z-index:15;opacity:0;transition:.2s;
}
.floating.show{opacity:1}
.float-pill{
  pointer-events:auto;display:flex;align-items:center;gap:12px;
  background:var(--pill-dark);color:#fff;border:none;cursor:pointer;font-family:inherit;
  font-size:18px;font-weight:600;padding:16px 34px;border-radius:34px;
  box-shadow:0 10px 26px rgba(0,0,0,.30);
}
.float-pill:active{filter:brightness(1.18)}
/* segmented pill (Barcode | QR) */
.float-multi{padding:0;gap:0;overflow:hidden}
.float-seg{display:flex;align-items:center;gap:10px;background:none;border:none;cursor:pointer;font-family:inherit;color:#fff;font-size:18px;font-weight:600;padding:16px 26px}
.float-seg:active{background:rgba(255,255,255,.12)}
.float-div{width:1px;align-self:stretch;background:rgba(255,255,255,.2);margin:11px 0}

/* ============ TIMETABLE ============ */
.tt-loading,.mb-loading{padding:30px;text-align:center;color:var(--muted);font-size:15px}

/* ── CARRUSEL DEL HORARIO ──────────────────────────────────────────────────────────────────────
   [ayer][hoy][manana] en una tira de tres anchos que el dedo arrastra 1:1, como las fotos de un
   carrusel. Sólo existe mientras el dedo está abajo: al soltar, el cuerpo vuelve a ser un solo día
   y estas reglas dejan de aplicar a nada.
   `align-items:flex-start` para que un día con pocas clases no se estire al alto del de al lado;
   `min-width:0` para que las tarjetas puedan encoger dentro de su panel. */
.tt-view{overflow-x:hidden}
.tt-track{display:flex;align-items:flex-start;width:300%;will-change:transform}
.tt-pane{flex:0 0 33.3333%;width:33.3333%;min-width:0}

/* El padding baja de 20 a 14 justo para que la FOTO pueda crecer sin que la fila crezca: la altura
   de la fila la manda la foto (es más alta que el texto), así que 94+40 y 106+28 miden lo mismo.
   Es lo que pidió Federico midiendo contra Glofox: más imagen, el mismo blanco. */
.tt-card{
  width:100%;display:flex;align-items:stretch;gap:14px;background:none;border:none;cursor:pointer;
  font-family:inherit;text-align:left;padding:14px 16px;border-bottom:1px solid var(--border);
}
.tt-card:active{background:#fafafb}
.tt-main{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}
.tt-name{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.tt-name-txt{font-size:22px;font-weight:700;color:#5b5c67;letter-spacing:.01em}
.tt-check{flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:#e6f4ea;color:#1a8f3c}
.tt-booked{flex:none;background:#111;color:#fff;font-size:13px;font-weight:700;padding:5px 12px;border-radius:14px}
.tt-sub{font-size:15px;color:var(--muted);margin-top:7px;line-height:1.34}
.tt-card.booked .tt-name-txt{color:#9c9ca2}
.tt-card.booked .tt-sub{color:#c0c0c4}
.tt-card.booked .tt-thumb{opacity:.4}
.tt-card.booked .tt-time{color:#a0a0a6}
/* Medido contra Glofox sobre la captura de Federico: allá la foto ocupa el 33% del ancho de la
   pantalla (≈143pt en un iPhone grande) y el 82% del alto de la fila; la nuestra iba en 29% y 70%.
   124x94 -> 140x106, y el padding de .tt-card baja de 20 a 14 para compensar: la fila mide lo
   mismo que antes y la foto se come el aire que sobraba. */
.tt-thumb{
  position:relative;width:140px;height:106px;flex:none;border-radius:8px;
  background:#ececed;overflow:hidden;
}
.tt-thumb img{width:100%;height:100%;object-fit:cover}
.tt-time{position:absolute;right:9px;bottom:7px;font-size:17px;font-weight:700;color:var(--ink)}
.tt-hour{display:none}   /* sólo escritorio — ver el bloque del final */

/* ============ BOOKINGS ============ */
/* pager horizontal deslizable — compartido: Bookings (.bk-*) y Memberships (.pgr-*) */
.bk-pager,.pgr{position:relative;overflow:hidden;height:100%;touch-action:pan-y}
.bk-track,.pgr-track{display:flex;height:100%;will-change:transform}
.bk-page,.pgr-page{flex:0 0 100%;height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}
.bk-wrap{display:flex;flex-direction:column;min-height:100%;padding:0 24px 26px}
.bk-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:36px 0}
.bk-empty-ic{
  width:82px;height:82px;border-radius:50%;background:#f1f1f2;color:#b7b7bc;
  display:flex;align-items:center;justify-content:center;margin-bottom:24px;
}
.bk-empty h3{margin:0 0 12px;font-size:23px;font-weight:700;color:var(--ink)}
.bk-empty p{margin:0;font-size:18px;color:#3f3f43;line-height:1.42;max-width:300px}
.bk-browse{
  width:100%;height:60px;border:none;border-radius:7px;background:var(--btn-gray);
  color:var(--btn-gray-ink);font-family:inherit;font-size:19px;font-weight:700;cursor:pointer;
}
.bk-browse:active{filter:brightness(.96)}

/* bookings list (Upcoming / Past sessions) */
.bk-wrap2{padding:22px 20px 26px}
.bk-list-h{margin:0;font-size:24px;font-weight:800;color:var(--ink);letter-spacing:-.01em}
.bk-list-sub{margin:6px 0 20px;font-size:16px;color:var(--muted)}
.bk-cards{display:flex;flex-direction:column;gap:16px}
.bk-card{position:relative;background:#fff;border:1px solid var(--border);border-radius:16px;padding:20px 18px;box-shadow:var(--shadow-card)}
.bk-card-menu{position:absolute;top:12px;right:8px;width:40px;height:40px;border:none;background:none;color:#8a8a90;cursor:pointer;display:flex;align-items:center;justify-content:center}
.bk-card-name{font-size:24px;font-weight:800;color:#26314f;letter-spacing:.01em;padding-right:36px}
.bk-card-body{display:flex;gap:14px;margin-top:10px}
.bk-card-left{flex:1;min-width:0}
.bk-card-meta{font-size:16px;color:var(--muted);line-height:1.35}
.bk-card-stats{display:flex;align-items:center;flex-wrap:wrap;gap:10px 16px;margin-top:16px}
.bk-stat{display:inline-flex;align-items:center;gap:6px;font-size:16px;color:var(--text)}
.bk-stat svg{flex:none;color:#8a8a90}
.bk-confirmed{display:inline-flex;align-items:center;gap:6px;background:var(--indigo-soft);color:var(--indigo);font-size:15px;font-weight:700;padding:6px 12px;border-radius:14px}
.bk-confirmed svg{flex:none;color:var(--indigo)}
.bk-card-thumb{position:relative;width:118px;height:94px;flex:none;border-radius:10px;background:#ececed;overflow:hidden}
.bk-card-thumb img{width:100%;height:100%;object-fit:cover}
.bk-card-time{position:absolute;right:8px;bottom:6px;background:#fff;border-radius:8px;padding:2px 8px;font-size:15px;font-weight:700;color:var(--ink)}

/* ============ MEMBERSHIPS ============ */
.mb-list{padding:2px 0 20px}
.mb-group{padding:24px 22px 30px;border-bottom:8px solid #efeff1}
.mb-group:last-child{border-bottom:none}
.mb-count{display:flex;align-items:center;gap:11px;color:#37373b;font-size:17px;font-weight:500;padding-bottom:16px;border-bottom:1px solid var(--border);margin-bottom:20px}
.mb-count svg{flex:none;color:#26262a}
.mb-name{margin:0 0 14px;font-size:23px;font-weight:700;color:var(--ink);letter-spacing:.004em}
.mb-desc{margin:0 0 24px;font-size:18px;line-height:1.5;color:#3b3b40}
.mb-view{
  width:100%;height:60px;border:none;border-radius:7px;background:var(--btn-gray);
  color:var(--btn-gray-ink);font-family:inherit;font-size:18px;font-weight:700;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:8px;position:relative;
}
.mb-view svg{position:absolute;right:18px;color:#141416}
.mb-view:active{filter:brightness(.96)}

/* ── LOS PLANES, DESPLEGADOS (sólo portal web) ───────────────────────────────────────────────
   En el teléfono NO se ven: ahí manda el botón "View membership plans" de arriba, porque una
   lista larga de precios tapa el resto de la página. Se pintan siempre y se esconden con CSS, no
   con un `if` de ancho — así cambiar el tamaño de la ventana funciona. */
.mb-plans{display:none}

/* ============ COMMUNITY ============ */
.cm-list{padding:0}
.cm-card{
  position:relative;display:block;width:100%;border:none;cursor:pointer;padding:0;
  margin:0;background:#101010;overflow:hidden;height:212px;
}
.cm-card + .cm-card{margin-top:3px}
.cm-media{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#343434}
.cm-media img{width:100%;height:100%;object-fit:cover}
.cm-shade{position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.04) 42%,rgba(0,0,0,.74) 100%)}
.cm-title{
  position:absolute;left:20px;right:20px;bottom:16px;text-align:left;
  color:#fff;font-size:26px;font-weight:800;line-height:1.1;letter-spacing:.004em;
}

/* ============ STORE ============ */
.st-heading{text-align:center;margin:22px 0 20px;font-size:23px;font-weight:700;color:var(--ink)}
.st-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 15px;padding:0 15px 28px}
.st-card{cursor:pointer}
.st-media{
  position:relative;width:100%;aspect-ratio:1/1;border-radius:4px;background:#f3f3f4;
  display:flex;align-items:center;justify-content:center;color:#c7c7cc;overflow:hidden;
  box-shadow:var(--shadow-card);
}
.st-media img{width:100%;height:100%;object-fit:cover}
/* Marca de DESTACADO (products.featured del CRM). Misma caja que traía la estrella de favoritos,
   pero sin cursor ni hover: no es un control del socio, es informativo. `pointer-events:none` para
   que un tap encima abra el producto igual que el resto de la tarjeta. */
.st-feat{
  position:absolute;left:11px;bottom:11px;width:34px;height:34px;border-radius:9px;
  background:rgba(238,238,238,.92);color:var(--star-on);display:flex;align-items:center;justify-content:center;
  pointer-events:none;
}
.st-name{margin-top:11px;font-size:20px;font-weight:700;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ============ SHARED EMPTY STATE ============ */
.empty{padding:64px 26px;text-align:center;color:var(--muted)}
.empty svg{color:var(--muted-2);margin-bottom:12px}
.empty h3{color:var(--ink);font-size:18px;margin:0 0 6px;font-weight:700}
.empty p{margin:0;font-size:15px;line-height:1.45}

/* ============ TOAST ============ */
.toast{
  position:absolute;left:50%;bottom:calc(var(--nav-h) + 24px);transform:translateX(-50%) translateY(8px);
  background:#1b1c1e;color:#fff;font-size:14px;font-weight:500;padding:11px 18px;border-radius:22px;
  /* z-index 60 = POR ENCIMA de .overlay-root (50). Estaba en 30, o sea DEBAJO: todo aviso que
     saliera con una capa abierta —la hoja de reserva, el detalle de la clase, el mapa de
     asientos— se pintaba tapado. Y ahí es justo donde la app tiene algo que decir: "esta clase
     está llena", "faltan datos de pago", "no te alcanzan los créditos". El resultado es que el
     botón parecía muerto: la app SÍ explicaba por qué y el socio no veía nada.
     Costó una tarde de "le doy Book y no pasa nada". */
  max-width:88%;text-align:center;opacity:0;pointer-events:none;transition:.2s;z-index:60;
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ============ PUSH SCREENS (overlay) ============ */
:root{ --indigo:#4b41c9; --indigo-soft:#ece9fb; }
.overlay-root{position:absolute;inset:0;z-index:50;pointer-events:none}
.screen{
  position:absolute;inset:0;background:#fff;pointer-events:auto;display:flex;flex-direction:column;
  transform:translateX(100%);transition:transform .24s cubic-bezier(.2,.8,.2,1);
  isolation:isolate;   /* own stacking context so z-indexed children never escape onto the screen above */
}
.screen.show{transform:translateX(0)}
/* {appear:true} — fade in place instead of sliding from the right */
.screen.appear{transform:none;opacity:0;transition:opacity .16s ease}
.screen.appear.show{opacity:1}
/* {fromLeft:true} — slide in from the left (left→right), used by the profile */
.screen.fromleft{transform:translateX(-100%)}
.screen.fromleft.show{transform:translateX(0)}
.tb-avatar{cursor:pointer;font-family:inherit;padding:0}

/* ============ CLASS DETAIL ============ */
.cd{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff}
.cd-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}

/* El hueco de la foto va en PROPORCIÓN de pantalla, no en 392px fijos. Federico lo pidió así
   midiéndolo contra Glofox: "casi la mitad de la página". Con un alto fijo se cumple sólo en el
   teléfono donde se midió — en un iPhone chico 392px son el 59% de la pantalla y en uno grande el
   42%. Con vh se ve igual en todos. El min-height protege pantallas muy bajas (o el teclado
   abierto en el navegador), donde 44vh dejaría el título encimado con los botones. */
.cd-hero{position:relative;height:44vh;min-height:300px;background:#161616 center/cover no-repeat;display:flex;flex-direction:column;justify-content:flex-end}
/* El alto NO cambia cuando no hay foto: es el mismo hueco de Glofox, y sin él la pantalla se
   siente distinta según la clase. Lo acorté una vez y estuvo mal — el espacio se respeta y lo que
   se ajustó fue el título. La foto la sube el gym en CRM > Sessions > la clase > Image. */
.cd-hero-grad{position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.34) 0%,rgba(0,0,0,.03) 32%,rgba(0,0,0,.58) 100%)}
/* ── Header fijo del detalle de clase ────────────────────────────────────────────────────────
   `sticky` + `margin-bottom` negativo del mismo alto = la barra se pega arriba PERO no ocupa
   lugar, así que la foto sigue empezando en el borde de la pantalla y la barra flota encima.
   El fondo va en un ::before y no en la barra, porque lo que se desvanece es el color: si le
   pusiéramos opacity a la barra entera desaparecerían también los botones. */
.cd-topbar{position:sticky;top:0;z-index:4;pointer-events:none;
  height:calc(env(safe-area-inset-top,0px) + 66px);
  margin-bottom:calc(-1 * (env(safe-area-inset-top,0px) + 66px))}
.cd-topbar::before{content:'';position:absolute;inset:0;background:var(--header);
  opacity:0;transition:opacity .22s ease}
.cd-topbar.on::before{opacity:1}
.cd-round{
  position:absolute;top:calc(env(safe-area-inset-top,0px) + 8px);width:52px;height:52px;border-radius:50%;
  border:none;background:#fff;color:#1a1a1a;cursor:pointer;display:flex;align-items:center;justify-content:center;
  z-index:2;box-shadow:0 2px 8px rgba(0,0,0,.20);pointer-events:auto;
}
.cd-back{left:16px}
.cd-share{right:16px}
/* El NOMBRE de la clase se queda pegado justo debajo de la barra mientras la foto sigue corriendo
   por detrás — se alcanza a ver la franja de foto que el título no tapa. Cuando la foto se acaba
   el título se va con ella: ése es su lugar, no un encabezado permanente.
   `sticky` en vez de `relative`: es lo mismo hasta que toca el tope. */
.cd-hero-body{position:sticky;top:calc(env(safe-area-inset-top,0px) + 66px);z-index:1;padding:0 22px 24px}
.cd-badge{display:inline-block;background:var(--btn-gray);color:var(--btn-gray-ink);font-size:15px;font-weight:700;padding:6px 14px;border-radius:9px;letter-spacing:.02em}
/* Se escala con el ancho y, si una palabra no cabe, se parte en vez de desbordar — el nombre de la
   clase lo escribe el gym y no tiene largo máximo ("PERMANENTE" sola medía 455px con el tamaño
   viejo, y la pantalla tiene 430).
   Bajó de 13vw (56px en un iPhone grande) a 8vw (34px): a Federico le pesaba demasiado. Con el
   nombre más discreto la pantalla se lee de un golpe en vez de empezar por un letrero. */
.cd-title{margin:10px 0 0;font-size:clamp(26px,8vw,36px);font-weight:800;color:#fff;line-height:1.04;
  letter-spacing:-.015em;overflow-wrap:break-word}
.cd-sub{margin-top:8px;font-size:19px;font-weight:500;color:#fff}
.cd-pastpill{display:inline-flex;align-items:center;gap:8px;margin-top:16px;background:rgba(20,20,22,.72);color:#fff;font-size:16px;font-weight:500;padding:11px 18px;border-radius:24px}
.cd-pastpill svg{flex:none}

.cd-sheet{position:relative;margin-top:-24px;background:#fff;border-radius:24px 24px 0 0;padding:24px 18px 24px}

.cd-when{display:flex;align-items:center;gap:16px;padding-bottom:22px;border-bottom:1px solid var(--border)}
.cd-when-ic{width:64px;height:64px;flex:none;border-radius:16px;background:var(--indigo-soft);color:var(--indigo);display:flex;align-items:center;justify-content:center}
.cd-when-main{flex:1;min-width:0}
.cd-when-date{font-size:17px;color:var(--muted);font-weight:500}
.cd-when-time{font-size:28px;font-weight:700;color:var(--ink);margin:2px 0;letter-spacing:-.01em}
.cd-when-dur{font-size:16px;color:var(--muted)}
.cd-when-sep{width:1px;align-self:stretch;background:var(--border);margin:4px 0}
/* Una sola línea, texto negro y discreto — como Glofox: "1 credit" o "$350", del mismo tamaño.
   Antes eran dos renglones con el número en 30px morado y una etiqueta abajo; pesaba más que la
   hora de la clase, que es lo que el socio viene a leer. */
.cd-when-credit{flex:none;border:1px solid #e5e5e8;border-radius:12px;padding:11px 16px;
  text-align:center;font-size:19px;font-weight:700;color:var(--ink);line-height:1.2;white-space:nowrap}

.cd-card{border:1px solid var(--border);border-radius:16px;padding:18px 18px 20px;margin-top:18px}
.cd-card-h{display:flex;align-items:center;gap:10px;color:var(--muted);font-size:14px;font-weight:700;letter-spacing:.06em;padding-bottom:16px;border-bottom:1px solid var(--border);margin-bottom:16px}
.cd-card-h svg{flex:none}

.cd-trainer-row{display:flex;align-items:center;gap:16px}
.cd-trainer-ph{width:72px;height:72px;flex:none;border-radius:50%;overflow:hidden;background:var(--indigo-soft);color:var(--indigo);display:flex;align-items:center;justify-content:center}
.cd-trainer-ph img{width:100%;height:100%;object-fit:cover}
.cd-trainer-info{flex:1;min-width:0}
.cd-trainer-name{font-size:22px;font-weight:700;color:var(--ink)}
.cd-trainer-role{font-size:16px;color:var(--text);margin-top:3px}
.cd-trainer-cert{font-size:15px;color:var(--indigo);font-weight:500;margin-top:2px}
.cd-trainer-chev{color:#c2c2c8;flex:none}

.cd-about-row{display:flex;gap:16px;align-items:flex-start}
.cd-about-ic{width:56px;height:56px;flex:none;border-radius:50%;background:var(--indigo-soft);color:var(--indigo);display:flex;align-items:center;justify-content:center}
.cd-about-txt{margin:0;flex:1;font-size:18px;line-height:1.45;color:var(--ink)}
.cd-tags{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
.cd-tag{background:#f4f4f5;border:1px solid var(--border);border-radius:10px;padding:9px 16px;font-size:15px;font-weight:500;color:var(--text)}

.cd-cta-wrap{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px));background:#fff}
.cd-cta{width:100%;height:62px;border:none;border-radius:14px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:19px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;position:relative}
.cd-cta svg{position:absolute;left:24px}
.cd-cta:active{filter:brightness(.95)}
/* booked state: green banner + flush sheet */
.cd-booked{display:flex;align-items:center;justify-content:center;gap:10px;background:#7fd90f;color:#123400;font-size:18px;font-weight:700;padding:15px 20px;position:relative;z-index:2}
.cd-booked svg{flex:none;color:#123400}
.cd-sheet.flush{margin-top:0;border-radius:0}
/* Cancelar lleva detalle rojo pero NO se pinta de rojo entero: el rojo lleno se reserva para el
   segundo tap (.confirm), que es el que de verdad cancela. Si los dos estados se vieran igual, el
   socio no distinguiría "voy a cancelar" de "ya cancelé". */
.cd-cta.cancel{background:#fff;color:#e5352b;box-shadow:inset 0 0 0 2px #f3c9c6}
.cd-cta.cancel:active{background:#fdf3f2}
.cd-cta.confirm{background:#fde8e8;color:#e5352b;box-shadow:inset 0 0 0 2px #e5352b}

/* ============ PROFILE ============ */
.pf{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff}
.pf-top{flex:none;display:flex;align-items:center;justify-content:space-between;padding:calc(env(safe-area-inset-top,0px) + 12px) 18px 4px}
.pf-topbtn{width:44px;height:44px;border:none;background:none;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#9a9aa0}
.pf-topbtn[data-back]{color:#c2c2c8}
.pf-logo{display:flex;align-items:center;justify-content:center}
.pf-logo img{max-width:56px;max-height:56px}
.pf-logo-txt{background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.14em;padding:16px 10px;border-radius:3px}

.pf-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:8px 20px 34px;text-align:center}
.pf-avatar{width:150px;height:150px;border-radius:50%;margin:6px auto 0;background:#e9e9ee center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#8a8a92;font-size:40px;font-weight:700}
.pf-name{margin:18px 0 0;font-size:34px;font-weight:700;color:var(--ink)}


/* estado de una membresía que ya no está viva. Chip discreto pegado al nombre: el socio necesita
   saber POR QUÉ le ofrecen renovar, pero el protagonista sigue siendo el nombre del plan. */
/* CUÁNDO vence, bajo el nombre del plan. Chico y apagado: el protagonista sigue siendo el plan. */

/* ── EL PERFIL ──────────────────────────────────────────────────────────────────────────────
   Rediseño que pidió Federico. La membresía deja de ser una fila igual a Credits o Family y se
   vuelve la pieza principal; lo demás baja de jerarquía a su alrededor. */

/* El saludo. El avatar deja de ser retrato central de 150px: la pantalla la abre quien YA sabe
   quién es, y la foto grande empujaba la membresía abajo del doblez. */
.pf-hello{display:flex;align-items:center;gap:14px;margin:4px 0 20px}
.pf-hello .pf-avatar{width:52px;height:52px;margin:0;flex:none;font-size:17px}
.pf-hello-txt{flex:1;min-width:0}
.pf-hello .pf-name{margin:0;font-size:24px;line-height:1.2;text-align:left}
.pf-hello .pf-email{margin:2px 0 0;text-align:left;font-size:13px}
.pf-edit{flex:none;background:none;border:none;cursor:pointer;font-family:inherit;font-size:15px;
  font-weight:600;color:var(--ink);text-decoration:underline;text-underline-offset:3px;padding:6px 2px}
/* hueco del lado derecho de la barra: el lápiz se mudó al saludo y sin esto el logo se descentra */
.pf-topbtn.is-ghost{pointer-events:none}

/* LA TARJETA DE MEMBRESÍA */
.pf-mem{--mem-cta:#dcebc6;--mem-cta-ink:#17220d;
  border-radius:18px;background:#14171b;color:#fff;padding:18px;margin-bottom:16px;text-align:left}
.pf-mem-head{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:24px}
.pf-mem-kicker{font-size:11px;font-weight:600;letter-spacing:1.2px;text-transform:uppercase;
  color:rgba(255,255,255,.55)}
/* La píldora dice el estado y lo dice CON COLOR: el socio lee el color antes que el texto, y un
   "Expired" del mismo tono que un "Auto-renewing" es justo lo que hace que un aviso no se vea. */
.pf-mem-pill{flex:none;padding:4px 11px;border-radius:999px;font-size:12px;font-weight:600;
  background:rgba(255,255,255,.13);color:rgba(255,255,255,.88)}
.pf-mem-pill:empty{display:none}
.pf-mem-pill.is-warn{background:#f2e3b8;color:#5b4713}
.pf-mem-pill.is-bad{background:#f7cfca;color:#7d2019}
.pf-mem-plan{font-size:29px;font-weight:700;line-height:1.1;color:#fff;margin-top:8px}
.pf-mem-sub{font-size:14px;color:rgba(255,255,255,.6);margin-top:5px}
.pf-mem-rule{height:1px;background:rgba(255,255,255,.14);margin:16px 0 14px}
.pf-mem-dateblock{display:flex;align-items:center;gap:12px}
.pf-mem-dl{flex:1;min-width:0}
.pf-mem-dlabel{display:block;font-size:13px;color:rgba(255,255,255,.6)}
.pf-mem-dvalue{display:block;font-size:22px;font-weight:700;color:#fff;margin-top:2px}
.pf-mem-dlabel:empty,.pf-mem-dvalue:empty{display:none}
.pf-mem-dicon{flex:none;width:42px;height:42px;border-radius:12px;display:flex;align-items:center;
  justify-content:center;background:rgba(255,255,255,.1);color:rgba(255,255,255,.75)}
/* La fecha llega DESPUÉS que la pantalla (renewTarget pide catálogo). Hasta entonces el bloque no
   existe: vacío ocupaba alto igual y la tarjeta daba un brinco al llegar la respuesta. Se esconde
   con una clase y no con :has() — no todos los WebView lo entienden, y ahí habría quedado el icono
   de calendario flotando solo. */
.pf-mem-dateblock{display:none}
.pf-mem-dateblock.on{display:flex}
.pf-mem-cta{width:100%;display:flex;align-items:center;justify-content:center;gap:10px;margin-top:18px;
  border:none;border-radius:12px;cursor:pointer;font-family:inherit;font-size:17px;font-weight:700;
  background:var(--mem-cta);color:var(--mem-cta-ink);padding:16px}
.pf-mem-cta svg{flex:none}
.pf-mem-link{display:block;width:100%;margin-top:14px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:14px;font-weight:600;color:rgba(255,255,255,.75);
  text-decoration:underline;text-underline-offset:3px;padding:2px 0}
/* a la recurrente no se le pinta botón (se cobra sola): el enlace queda como única acción */
.pf-mem.is-auto .pf-mem-link{margin-top:18px}

/* LOS DOS MOSAICOS */
.pf-tiles{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:24px}
.pf-tile{display:flex;flex-direction:column;align-items:flex-start;gap:2px;border:1px solid var(--border);
  border-radius:14px;background:#fff;cursor:pointer;font-family:inherit;padding:14px;text-align:left}
.pf-tile-top{display:flex;align-items:center;justify-content:space-between;width:100%;
  color:#9a9aa0;margin-bottom:8px}
.pf-tile-top svg:last-child{transform:rotate(-45deg)}
.pf-tile-title{font-size:17px;font-weight:700;color:var(--ink);line-height:1.2}
.pf-tile-sub{font-size:12px;color:var(--muted)}

/* LA CUENTA */
.pf-sect{font-size:11px;font-weight:600;letter-spacing:1.2px;text-transform:uppercase;
  color:var(--muted);margin-bottom:4px;text-align:left}
.pf-row-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.pf-row-sub{font-size:13px;color:var(--muted);text-align:left}

/* El AVISO de vencimiento en Bookings. Ancho completo y tocable entero: es una sola acción. */
.bk-renew{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;
  border:none;cursor:pointer;font-family:inherit;text-align:left;
  background:#fff7e6;border-left:3px solid #e0a300;padding:12px 16px}
.bk-renew.gone{background:#fdecea;border-left-color:#c0392b}
.bk-renew-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.bk-renew-txt b{font-size:15px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk-renew-txt span{font-size:13px;color:#7a6a3a}
.bk-renew.gone .bk-renew-txt span{color:#a33}
.bk-renew-cta{flex:none;font-size:15px;font-weight:700;color:var(--ink);text-decoration:underline;
  text-underline-offset:3px}

/* "Your plan" en el catálogo: sólo sale mientras la membresía SIGUE siendo suya. */
.mb-group.mine{border:1px solid #d8d8db;border-radius:14px;padding:14px;background:#fcfcfd}
.mb-mine{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.3px;text-transform:uppercase;
  color:#1a8f3c;background:#e6f4ea;border-radius:999px;padding:3px 10px;margin-bottom:8px}


.pf-ic{width:48px;height:48px;flex:none;border-radius:50%;background:#eeeef0;color:#565660;display:flex;align-items:center;justify-content:center}
.pf-ic.sm{width:44px;height:44px;background:#f1f1f3;color:#9a9aa0}

.pf-rows{margin-top:18px;text-align:left}
.pf-row{width:100%;display:flex;align-items:center;gap:16px;background:none;border:none;border-bottom:1px solid var(--border);cursor:pointer;font-family:inherit;padding:15px 2px}
.pf-row-label{font-size:18px;color:var(--ink);font-weight:600;text-align:left}
.pf-row > svg{color:#c4c4ca;flex:none}
/* interruptor (fila Face ID del perfil): el color de marca cuando está prendido */
.pf-switch{flex:none;position:relative;width:44px;height:26px;border-radius:13px;background:#d9d9de;transition:background .18s ease}
.pf-switch::after{content:'';position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.22);transition:transform .18s ease}
.pf-switch.on{background:var(--header)}
.pf-switch.on::after{transform:translateX(18px)}
.pf-row:disabled .pf-switch{opacity:.6}

/* ============ BUY CREDITS ============ */
.cr-list{padding:2px 0 20px}
.cr-group{padding:22px 0 26px;border-bottom:8px solid #efeff1}
.cr-group:last-child{border-bottom:none}
.cr-name{margin:0 22px 18px;font-size:22px;font-weight:700;color:var(--ink)}
.cr-table{display:flex;border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.cr-col{padding:15px 0 18px}
.cr-total{flex:0 0 30%;padding-left:22px;border-right:1px solid var(--border)}
.cr-price{flex:1;padding-left:24px}
.cr-col-h{font-size:15px;font-weight:700;letter-spacing:.09em;color:#3b3b3f}
.cr-col-v{font-size:30px;font-weight:400;color:var(--ink);margin-top:12px;letter-spacing:-.01em}
.cr-buy{
  display:block;margin:22px 22px 0;width:calc(100% - 44px);height:64px;border:none;border-radius:7px;
  background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:20px;font-weight:700;
  cursor:pointer;box-shadow:0 3px 6px rgba(0,0,0,.09);
}
.cr-buy:active{filter:brightness(.96)}

/* ============ CLASS DETAIL — compact multi-coach + quick sheet + Book CTA ============ */
.cd-coach-list{display:flex;flex-direction:column}
.cd-coach{display:flex;align-items:center;gap:14px;width:100%;background:none;border:none;cursor:pointer;font-family:inherit;text-align:left;padding:11px 0}
.cd-coach:active{opacity:.6}
.cd-coach + .cd-coach{border-top:1px solid var(--border)}
.cd-coach-ph{width:50px;height:50px;flex:none;border-radius:50%;overflow:hidden;background:var(--indigo-soft);color:var(--indigo);display:flex;align-items:center;justify-content:center}
.cd-coach-ph img{width:100%;height:100%;object-fit:cover}
.cd-coach-info{flex:1;min-width:0;display:flex;flex-direction:column}
.cd-coach-name{font-size:18px;font-weight:700;color:var(--ink)}
.cd-coach-role{font-size:15px;color:var(--muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-coach > svg{color:#c2c2c8;flex:none}

/* Book CTA (upcoming class): same gray as the other buttons, arrow on the right */
.cd-cta.book svg{left:auto;right:24px}

/* ============ COACH PROFILE (full screen from a class-detail coach) ============ */
.cp{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff}
.cp-top{flex:none;display:flex;align-items:center;justify-content:space-between;padding:calc(env(safe-area-inset-top,0px) + 12px) 18px 4px}
.cp-close{width:44px;height:44px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.cp-logo{display:flex;align-items:center;justify-content:center}
.cp-logo img{max-width:56px;max-height:56px}
.cp-logo-txt{background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.14em;padding:16px 10px;border-radius:3px}
.cp-top-sp{width:44px;flex:none}

.cp-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 22px 24px;text-align:center}
.cp-avatar{width:220px;height:220px;max-width:60vw;max-height:60vw;border-radius:50%;margin:8px auto 0;background:#e9e9ee center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#8a8a92;font-size:52px;font-weight:700}
.cp-name{margin:20px 0 0;font-size:38px;font-weight:700;color:var(--ink)}
.cp-role{font-size:22px;color:var(--muted);margin-top:6px}

.cp-stats{display:flex;justify-content:space-between;gap:12px;padding:24px 4px;margin-top:22px;border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.cp-stat{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px}
.cp-stat-ic{color:var(--ink);height:26px;display:flex;align-items:center}
.cp-stat-v{font-size:26px;font-weight:700;color:var(--ink)}
.cp-stat-l{font-size:15px;color:var(--muted)}

.cp-about{text-align:left;padding:22px 0;border-bottom:1px solid var(--border)}
.cp-h{margin:0 0 12px;font-size:22px;font-weight:700;color:var(--ink)}
.cp-about-txt{margin:0;font-size:18px;line-height:1.5;color:var(--text)}

.cp-classes{text-align:left;padding:22px 0 0}
.cp-classes-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:16px}
.cp-full{background:none;border:none;cursor:pointer;font-family:inherit;color:var(--indigo);font-size:17px;font-weight:600;padding:0}
.cp-class-list{display:flex;flex-direction:column;gap:14px}
.cp-class{display:flex;align-items:center;gap:16px;width:100%;border:1px solid var(--border);border-radius:14px;background:#fff;cursor:pointer;font-family:inherit;text-align:left;padding:16px}
.cp-class:active{background:#fafafb}
.cp-date{flex:none;width:66px;background:#f4f4f5;border-radius:10px;padding:10px 0;text-align:center;display:flex;flex-direction:column;gap:1px}
.cp-date-wd{font-size:13px;font-weight:600;color:var(--muted);letter-spacing:.03em}
.cp-date-day{font-size:26px;font-weight:700;color:var(--ink);line-height:1.05}
.cp-date-mo{font-size:13px;font-weight:600;color:var(--muted);letter-spacing:.03em}
.cp-class-main{flex:1;min-width:0;display:flex;flex-direction:column}
.cp-class-name{font-size:18px;font-weight:700;color:var(--ink)}
.cp-class-meta{display:flex;align-items:center;gap:10px;margin-top:6px}
.cp-class-time{font-size:15px;color:var(--muted)}
.cp-credit-pill{background:var(--indigo-soft);color:var(--indigo);font-size:13px;font-weight:600;padding:3px 10px;border-radius:12px}
.cp-class > svg{color:#c2c2c8;flex:none}

.cp-cta-wrap{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px));background:#fff}
.cp-back{width:100%;height:62px;border:none;border-radius:12px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:20px;font-weight:700;cursor:pointer}
.cp-back:active{filter:brightness(.96)}

/* ============ PRODUCT DETAIL (modern e-commerce) ============ */
.pd{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.pd-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}

.pd-hero{position:relative;height:300px;background:#e7e7ea;display:flex;align-items:center;justify-content:center}
.pd-media{width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#b9b9bf}
.pd-media img{width:100%;height:100%;object-fit:cover}
.pd-round{
  position:absolute;top:calc(env(safe-area-inset-top,0px) + 14px);width:52px;height:52px;border-radius:50%;
  border:none;background:#fff;color:#1a1a1a;cursor:pointer;display:flex;align-items:center;justify-content:center;
  z-index:2;box-shadow:0 2px 8px rgba(0,0,0,.16);
}
.pd-back{left:14px}
.pd-hero-actions{position:absolute;top:calc(env(safe-area-inset-top,0px) + 14px);right:14px;display:flex;gap:12px;z-index:2}
.pd-hero-actions .pd-round{position:static}
.pd-cart-badge{position:absolute;top:-4px;right:-4px;min-width:22px;height:22px;padding:0 5px;border-radius:11px;background:#1b1c1e;color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #fff}
.pd-hero-actions .pd-round{position:relative}
.pd-dots{position:absolute;left:0;right:0;bottom:22px;display:flex;justify-content:center;gap:8px;z-index:1}
.pd-dot{width:8px;height:8px;border-radius:50%;background:rgba(20,20,25,.24)}
.pd-dot.on{background:#3a3a40}
.pd-zoom{position:absolute;right:14px;bottom:16px;display:flex;align-items:center;gap:8px;background:#fff;border:none;border-radius:22px;padding:11px 16px;font-family:inherit;font-size:16px;font-weight:500;color:var(--ink);cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.14);z-index:2}
.pd-zoom svg{color:var(--muted)}

.pd-body{padding:20px 20px 22px}
.pd-featured{display:inline-flex;align-items:center;gap:7px;background:#ededee;color:#1a1a1c;font-size:15px;font-weight:600;letter-spacing:.04em;padding:8px 14px;border-radius:10px;margin-bottom:16px}
.pd-featured svg{color:#1a1a1c}
.pd-title{margin:0;font-size:34px;font-weight:800;color:var(--ink);line-height:1.06;letter-spacing:-.01em}
.pd-price{margin-top:14px;font-size:22px;color:var(--muted)}
.pd-price b{font-size:28px;font-weight:700;color:var(--ink)}
.pd-cur{font-size:20px;font-weight:500;color:var(--muted);margin-left:4px}
.pd-desc{margin-top:18px;font-size:20px;line-height:1.4;color:var(--text)}
.pd-desc strong{font-weight:700;color:var(--ink)}
.pd-divider{height:1px;background:var(--border);margin:22px 0}
.pd-size-label{font-size:15px;font-weight:700;letter-spacing:.09em;color:#3b3b3f}
.pd-sizes{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:16px}
.pd-size{height:66px;border:1.5px solid #dcdce0;border-radius:12px;background:#fff;font-family:inherit;font-size:20px;font-weight:600;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.pd-sizes:has(.pd-size:only-child) .pd-size,.pd-size{min-width:0}
.pd-size.sel{border-color:var(--ink);border-width:2px}
.pd-size.off{color:#b8b8be;cursor:default;background:linear-gradient(to top right,transparent calc(50% - 1px),#dcdce0 calc(50% - 1px),#dcdce0 calc(50% + 1px),transparent calc(50% + 1px))}
.pd-stock{display:flex;align-items:center;gap:9px;margin-top:18px;font-size:16px;color:var(--text)}
.pd-stock-dot{width:11px;height:11px;border-radius:50%;background:#12a45a;flex:none}

.pd-foot{flex:none;background:#fff;border-top:1px solid var(--border);border-radius:20px 20px 0 0;box-shadow:0 -6px 20px rgba(0,0,0,.06);padding:14px 16px calc(10px + env(safe-area-inset-bottom,0px))}
/* .pd-foot-price se fue con su marcado: era un segundo precio, fijo en el de la primera variante,
   que contradecía al de arriba en cuanto el producto tenía tallas. El precio vive en .pd-price. */
.pd-foot-row{display:flex;align-items:center;gap:14px;margin-bottom:12px}
.pd-addcart{flex:1;height:56px;border:none;border-radius:30px;background:#1b1c1e;color:#fff;font-family:inherit;font-size:18px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:10px}
.pd-addcart:active{filter:brightness(1.15)}
.pd-addcart.off,.pd-addcart:disabled{background:#cbcbd0;color:#fff;cursor:not-allowed}
.pd-addcart.off:active,.pd-addcart:disabled:active{filter:none}
.pd-checkout{width:100%;height:50px;border:none;border-radius:12px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:17px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;position:relative}
.pd-checkout-count{position:absolute;left:14px;min-width:26px;height:26px;padding:0 7px;border-radius:13px;background:var(--ink);color:#fff;font-size:14px;font-weight:700;display:flex;align-items:center;justify-content:center}
.pd-checkout-count.bump{animation:pdBump .3s ease}
@keyframes pdBump{0%{transform:scale(1)}40%{transform:scale(1.45)}100%{transform:scale(1)}}
.pd-checkout svg{position:absolute;right:20px}
.pd-checkout:active{filter:brightness(.96)}
.pd-checkout.off,.pd-checkout:disabled{background:#ededee;color:#b8b8bd;cursor:not-allowed}
.pd-checkout.off .pd-checkout-count,.pd-checkout:disabled .pd-checkout-count{background:#c9c9ce;color:#fff}
.pd-checkout.off:active,.pd-checkout:disabled:active{filter:none}

/* ============ COMMUNITY POST DETAIL ============ */
.co{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.co-head{position:absolute;top:0;left:0;right:0;z-index:3;padding-top:max(env(safe-area-inset-top,0px), var(--statusbar));transition:background .2s}
.co-head.solid{background:var(--header)}
.co-head-bar{position:relative;height:44px;display:flex;align-items:center;justify-content:center}
.co-back{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;filter:drop-shadow(0 1px 3px rgba(0,0,0,.5))}
.co-head-title{color:#fff;font-size:22px;font-weight:700;opacity:0;transition:opacity .2s}
.co-head.solid .co-head-title{opacity:1}
.co-head.solid .co-back{filter:none}

.co-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
.co-hero{height:452px;background:#1c1c1e center/cover no-repeat;display:flex;align-items:center;justify-content:center}
.co-hero-ph{color:#3a3a3c}
.co-body{padding:22px 20px 34px}
.co-title{margin:0 0 12px;font-size:34px;font-weight:800;color:var(--ink);line-height:1.08;letter-spacing:-.005em}
.co-pub{font-size:18px;color:var(--text);margin-bottom:22px}
.co-pub b{font-weight:700;color:var(--ink)}
.co-para{margin:0 0 22px;font-size:19px;line-height:1.45;color:var(--ink)}
.co-tagrow{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:8px}
.co-tag-label{font-size:19px;font-weight:700;color:var(--ink);margin-right:2px}
.co-tag{background:#f1f1f3;border:1px solid var(--border);border-radius:18px;padding:8px 18px;font-size:16px;font-weight:600;color:var(--text)}

/* ============ CART ============ */
.ct{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.ct-top{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:calc(env(safe-area-inset-top,0px) + 12px) 16px 10px}
.ct-close{position:absolute;left:12px;top:calc(env(safe-area-inset-top,0px) + 8px);width:44px;height:44px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.ct-title{font-size:24px;font-weight:700;color:var(--ink)}
.ct-bag{position:absolute;right:14px;top:calc(env(safe-area-inset-top,0px) + 8px);width:44px;height:44px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.ct-bag-badge{position:absolute;top:2px;right:2px;min-width:20px;height:20px;padding:0 5px;border-radius:10px;background:#1b1c1e;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center}

.ct-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:8px 18px 20px}

.ct-pickup{display:flex;align-items:center;gap:14px;background:#f3f3f5;border-radius:14px;padding:16px}
.ct-pickup-ic{width:44px;height:44px;flex:none;border-radius:50%;background:#e5e5e9;color:#4a4a50;display:flex;align-items:center;justify-content:center}
.ct-pickup-h{font-size:19px;font-weight:700;color:var(--ink)}
.ct-pickup-sub{font-size:16px;color:var(--text);margin-top:2px}

.ct-items{padding:4px 0}
.ct-item{display:flex;gap:16px;padding:18px 0;border-bottom:1px solid var(--border)}
.ct-item-img{width:96px;height:96px;flex:none;border-radius:10px;background:#f1f1f3;overflow:hidden;display:flex;align-items:center;justify-content:center;color:#c2c2c8}
.ct-item-img img{width:100%;height:100%;object-fit:cover}
.ct-item-body{flex:1;min-width:0}
.ct-item-name{font-size:20px;font-weight:700;color:var(--ink);line-height:1.15}
.ct-item-variant{font-size:16px;color:var(--muted);margin-top:5px}
.ct-item-bottom{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:14px}
.ct-item-price{font-size:21px;font-weight:700;color:var(--ink)}
.ct-item-ctl{display:flex;align-items:center;gap:8px}
.ct-qty{display:flex;align-items:center;background:#f1f1f3;border-radius:12px;padding:4px}
.ct-qty button{width:34px;height:34px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.ct-qty span{min-width:38px;height:34px;background:#fff;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:700;color:var(--ink)}
.ct-del{width:40px;height:40px;border:none;background:none;color:#9a9aa0;cursor:pointer;display:flex;align-items:center;justify-content:center}

.ct-summary{padding:18px 0 4px}
.ct-sum-row{display:flex;align-items:center;justify-content:space-between;padding:7px 0;font-size:18px;color:var(--text)}
.ct-tax{display:inline-flex;align-items:center;gap:6px}
.ct-tax svg{color:var(--muted)}
.ct-sum-divider{height:1px;background:var(--border);margin:12px 0}
.ct-sum-row.total span{font-size:24px;font-weight:700;color:var(--ink)}

.ct-pay{display:flex;align-items:center;gap:14px;padding:18px 0;border-top:1px solid var(--border);margin-top:6px}
.ct-pay-brand{flex:none;background:#fff;border:1px solid var(--border);border-radius:6px;padding:6px 9px;font-size:13px;font-weight:800;font-style:italic;color:#1a1f71;letter-spacing:.02em}
.ct-pay-label{flex:1;min-width:0;font-size:18px;color:var(--ink)}
.ct-pay-change{display:inline-flex;align-items:center;gap:1px;background:none;border:none;cursor:pointer;font-family:inherit;color:var(--indigo);font-size:18px;font-weight:600}
.ct-pay-change svg{color:var(--indigo)}

.ct-foot{flex:none;background:#fff;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.ct-pay-btn{width:100%;height:62px;border:none;border-radius:14px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:19px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;position:relative}
.ct-pay-btn svg{position:absolute;right:24px}
.ct-pay-btn:active{filter:brightness(.96)}
.ct-empty{padding:60px 20px;text-align:center;color:var(--muted);font-size:17px}

/* ============ MEMBERSHIP PLANS (from "View membership plans") ============ */
.mp{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.mp-top{flex:none;display:flex;align-items:center;justify-content:space-between;padding:calc(env(safe-area-inset-top,0px) + 12px) 18px 4px}
.mp-back{width:44px;height:44px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.mp-logo{display:flex;align-items:center;justify-content:center}
.mp-logo img{max-width:56px;max-height:56px}
.mp-logo-txt{background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.14em;padding:16px 10px;border-radius:3px}
.mp-top-sp{width:44px;flex:none}

.mp-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:14px 20px 30px}
.mp-title{margin:8px 0 0;font-size:32px;font-weight:800;color:var(--ink);line-height:1.08;letter-spacing:-.01em}
.mp-desc{margin:16px 0 0;font-size:18px;line-height:1.5;color:var(--text)}
.mp-section{margin:30px 0 16px;font-size:16px;font-weight:700;letter-spacing:.06em;color:var(--ink)}

.mp-plans{display:flex;flex-direction:column;gap:16px}
.mp-card{position:relative;border:1px solid var(--border);border-radius:14px;padding:22px 15px 18px;background:#fff}
.mp-card.popular{border:2px solid var(--ink)}
.mp-card-top{padding:0 3px}
.mp-badge{position:absolute;top:-13px;left:20px;background:var(--ink);color:#fff;font-size:13px;font-weight:700;letter-spacing:.05em;padding:6px 12px;border-radius:8px}
.mp-card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.mp-card-dur{font-size:22px;font-weight:700;color:var(--ink)}
.mp-card-billed{font-size:16px;color:var(--muted);margin-top:5px}
.mp-card-right{text-align:right;flex:none}
.mp-card-price{font-size:26px;font-weight:700;color:var(--ink)}
.mp-card-permonth{font-size:15px;color:var(--muted);margin-top:4px}
.mp-card-divider{height:1px;background:var(--border);margin:18px 0}
.mp-card-bottom{display:flex;align-items:center}
.mp-card-detail{flex:1;min-width:0;font-size:14px;color:var(--text);line-height:1.4}
.mp-dot{margin:0 6px;color:var(--muted-2)}
.mp-select{width:100%;height:56px;margin-top:16px;border:none;border-radius:10px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:17px;font-weight:700;letter-spacing:.03em;cursor:pointer}
.mp-select:active{filter:brightness(.96)}

.mp-note{display:flex;align-items:flex-start;gap:14px;background:#f3f3f5;border-radius:14px;padding:18px;margin-top:22px}
.mp-note-ic{flex:none;color:var(--muted);margin-top:1px}
.mp-note-txt{font-size:16px;color:var(--text);line-height:1.4}

/* ============ REVIEW PURCHASE (membership checkout) ============ */
.rp{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.rp-top{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:calc(env(safe-area-inset-top,0px) + 14px) 18px 12px}
.rp-title{font-size:22px;font-weight:700;color:var(--ink)}
.rp-close{position:absolute;right:12px;top:calc(env(safe-area-inset-top,0px) + 10px);width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.rp-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:8px 20px 20px}

.rp-card{background:#f3f3f5;border-radius:12px;padding:20px 18px}
.rp-card-head{display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.rp-card-headleft{min-width:0}
.rp-card-name{font-size:24px;font-weight:700;color:var(--ink);letter-spacing:.005em}
.rp-card-dur{font-size:17px;color:var(--muted);margin-top:4px;text-transform:uppercase;letter-spacing:.02em}
.rp-showdetails{flex:none;display:flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;font-family:inherit;font-size:17px;color:var(--ink);font-weight:500;white-space:nowrap}
.rp-showdetails svg{color:var(--ink)}
.rp-details{margin-top:18px;border-top:1px solid #e2e2e6;padding-top:16px;display:flex;flex-direction:column;gap:12px}
.rp-detail-row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:16px;color:var(--muted)}
.rp-detail-row span:last-child{color:var(--ink);font-weight:600;text-align:right}

.rp-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:22px 2px}
.rp-row-label{font-size:19px;color:var(--ink)}
.rp-row-val{font-size:24px;font-weight:700;color:var(--ink)}
.rp-divider{height:1px;background:var(--border)}
.rp-change{display:flex;align-items:center;gap:8px;background:none;border:none;cursor:pointer;font-family:inherit;font-size:18px;font-weight:700;color:var(--ink)}
.rp-change svg{color:var(--ink)}

.rp-promo{padding:20px 2px}
.rp-promo-label{font-size:19px;font-weight:700;color:var(--ink);margin-bottom:14px}
.rp-promo-input{width:100%;height:56px;border:1px solid #d0d0d5;border-radius:10px;padding:0 16px;font-family:inherit;font-size:17px;color:var(--ink);background:#fff;outline:none}
.rp-promo-input:focus{border-color:#9a9aa0}
.rp-promo-input::placeholder{color:var(--muted)}

.rp-summary{width:100%;display:flex;align-items:center;justify-content:space-between;background:none;border:none;cursor:pointer;font-family:inherit;padding:22px 2px;font-size:19px;font-weight:700;color:var(--ink)}
.rp-summary svg{color:var(--ink)}
.rp-summary-body{padding:0 2px 16px}
.rp-sum-row{display:flex;align-items:center;justify-content:space-between;font-size:17px;color:var(--text)}
/* Por qué se perdonó la inscripción ("Waived — returning member"). Va chico y apagado: el
   protagonista es el renglón de arriba; esto sólo explica por qué no se cobra. */
.rp-quote-note{font-size:13px;color:var(--muted);margin:-2px 0 6px;line-height:1.35}
/* El servidor dijo que esta compra no procede. En rojo y legible: deja el botón apagado, así que
   el socio necesita entender por qué sin tener que adivinar. */
.rp-quote-err{font-size:14px;color:#c0392b;margin:2px 0 6px;line-height:1.4}

.rp-total-label{font-size:19px;font-weight:700;color:var(--ink)}
.rp-total-val{font-size:24px;font-weight:700;color:var(--ink)}
.rp-terms{padding:18px 2px 0;font-size:16px;color:var(--text);line-height:1.4}
.rp-terms a{color:var(--ink);text-decoration:underline;cursor:pointer}

.rp-foot{flex:none;background:#fff;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.rp-purchase{width:100%;height:60px;border:none;border-radius:8px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:20px;font-weight:700;cursor:pointer;box-shadow:0 3px 6px rgba(0,0,0,.09)}
.rp-purchase:active{filter:brightness(.96)}

/* ============ REVIEW BOOKING (bottom sheet, from tapping a class photo) ============ */
.rb-overlay{position:absolute;inset:0;z-index:50;background:rgba(15,15,20,.44);display:flex;align-items:flex-end;opacity:0;transition:opacity .25s;pointer-events:auto;padding-top:max(env(safe-area-inset-top,0px), var(--statusbar))}
.rb-overlay.show{opacity:1}
.rb-sheet{width:100%;height:100%;background:#fff;border-radius:20px 20px 0 0;transform:translateY(100%);transition:transform .28s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column;overflow:hidden}
.rb-overlay.show .rb-sheet{transform:translateY(0)}

.rb-head{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:20px 18px 14px}
.rb-title{font-size:22px;font-weight:700;color:var(--ink)}
.rb-close{position:absolute;right:12px;top:14px;width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}

.rb-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 20px 10px}
.rb-card{background:#f3f3f5;border-radius:12px;padding:20px 18px;margin-bottom:8px}
.rb-card-name{font-size:26px;font-weight:700;color:var(--ink);letter-spacing:.01em}
.rb-card-sub{font-size:18px;color:var(--muted);margin-top:6px}

.rb-fee{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:22px 2px}
.rb-fee-label{font-size:19px;color:var(--ink)}
.rb-fee-val{font-size:26px;font-weight:700;color:var(--ink)}
.rb-divider{height:1px;background:var(--border)}

.rb-friend{display:flex;align-items:center;justify-content:space-between;gap:12px;background:#f3f3f5;border-radius:12px;padding:16px 18px;margin-top:14px}
.rb-friend-label{font-size:21px;font-weight:700;color:var(--ink)}
.rb-stepper{display:flex;align-items:center;gap:14px}
.rb-step{width:44px;height:44px;border:none;border-radius:50%;background:#e4e4e8;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.rb-step:active{filter:brightness(.94)}
.rb-step:disabled{opacity:.4;cursor:not-allowed}
.rb-count{min-width:20px;text-align:center;font-size:20px;font-weight:700;color:var(--ink)}

/* La tarjeta con foto pasa a dos columnas: la imagen a la izquierda y el texto a la derecha.
   Sin foto se queda en una, y así una clase sin imagen no deja un marco vacío. */
.rb-card.with-pic{display:grid;grid-template-columns:96px minmax(0,1fr);gap:14px;align-items:start}
.rb-card-pic{width:96px;height:96px;border-radius:10px;background:#e4e4e8 center/cover no-repeat}
.rb-card-txt{min-width:0}
.rb-card-coach{display:flex;align-items:center;gap:7px;margin-top:8px;
  font-size:16px;font-weight:600;color:var(--ink)}
.rb-card-coach svg{flex:none;color:var(--muted)}
.rb-card-spots{display:flex;align-items:center;gap:7px;margin-top:10px;width:100%;
  background:none;border:none;padding:0;font-family:inherit;cursor:pointer;text-align:left;
  color:var(--ink);font-size:16px;font-weight:700}
.rb-card-spots svg{flex:none;color:var(--muted)}
.rb-spots-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* "Change" con el mismo peso y el mismo lápiz que el de la tarjeta: si las dos filas editables de
   la hoja se tocan igual, no hay que aprender dos gestos. */
.rb-spots-ch{display:inline-flex;align-items:center;gap:5px;flex:none;
  font-size:15px;font-weight:700;color:var(--ink)}
.rb-spots-ch svg{color:var(--ink)}
.rb-card-spots:active{opacity:.55}


/* ⚠️ ESTAS REGLAS LAS BORRE YO. Las escribio f913b60 junto con el marcado de la fila
   tarjeta|cupon, y mi commit d185d37 —el de la tarjeta del perfil— se las llevo por delante al
   reemplazar un bloque del CSS. El marcado quedo vivo y sin estilo: la tarjeta y el cupon salian
   como controles crudos del navegador, en el telefono tambien, y asi estuvieron todo el dia hasta
   que Federico lo vio ("esta raro lo de la tarjeta y el promo code").
   Van recuperadas TAL CUAL del commit que las creo, no reescritas de memoria. */
/* ── TARJETA | CUPÓN, mitad y mitad ────────────────────────────────────────────────────────
   Antes eran dos filas completas y el cupón acababa debajo del corte. Las dos son "toca para
   cambiar algo", así que se ven igual: misma altura, mismo fondo, mismo peso. */
.rb-row2{display:flex;align-items:stretch;gap:8px;padding:10px 2px 2px}
.rb-half{flex:1;min-width:0;display:flex;align-items:center;gap:8px;height:52px;
  background:#f3f3f5;border:1px solid transparent;border-radius:12px;padding:0 12px;
  font-family:inherit;cursor:pointer;text-align:left}
.rb-half svg{flex:none;color:var(--muted)}
.rb-half-v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:15px;font-weight:700;color:var(--ink)}
.rb-pay2:active{filter:brightness(.95)}
/* el cupón NO es un botón: es una caja de texto, y se ve como tal (fondo blanco, borde) */
.rb-promo2{background:#fff;border-color:#dcdce0;padding:0 6px 0 12px;cursor:text}
.rb-promo2:focus-within{border-color:#111}
.rb-promo2.on{background:#f3f3f5}
.rb-promo-in2{flex:1;min-width:0;height:100%;border:none;background:none;outline:none;
  font-family:inherit;font-size:15px;font-weight:700;color:var(--ink);letter-spacing:.04em;
  text-transform:uppercase}
.rb-promo-in2::placeholder{font-weight:500;letter-spacing:normal;text-transform:none;color:#a3a3a9}
.rb-promo-go2{flex:none;width:34px;height:34px;border:none;border-radius:9px;background:var(--header);
  color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
.rb-promo-go2 svg{color:#fff}
.rb-promo-go2:disabled{background:#e4e4e8}
.rb-promo-go2:disabled svg{color:#b6b6bb}

/* Promo code. Discreto a propósito: el que trae código lo busca, y al que no lo tiene no hay que
   recordarle que existe un precio mejor justo antes de cobrarle. */
.rb-promo{display:flex;flex-direction:column;gap:6px;padding:16px 2px 4px}
.rb-promo-in{height:50px;border:1px solid #dcdce0;border-radius:12px;padding:0 15px;background:#fff;
  font-family:inherit;font-size:16px;font-weight:600;color:var(--ink);letter-spacing:.06em;
  text-transform:uppercase;outline:none;width:100%}
.rb-promo-in:focus{border-color:#111}
.rb-promo-in::placeholder{color:#a3a3a9;font-weight:500;letter-spacing:normal;text-transform:none}
.rb-promo-in[readonly]{background:#f5f5f7;color:var(--muted)}
.rb-promo-row{display:flex;align-items:center;gap:8px}
.rb-promo-go{flex:none;height:50px;padding:0 18px;border:none;border-radius:12px;background:var(--header);
  color:#fff;font-family:inherit;font-size:15px;font-weight:700;cursor:pointer}
.rb-promo-go:disabled{opacity:.35}
.rb-promo-go:active:not(:disabled){filter:brightness(1.3)}
/* el veredicto del código. Vacío = sin mensaje, y entonces no ocupa ni el renglón. */
.rb-promo-note{font-size:13.5px;color:var(--muted);padding-left:2px}
.rb-promo-note:empty{display:none}
.rb-promo-note.ok{color:#1a8f4c;font-weight:600}
.rb-promo-note.bad{color:#d0342c;font-weight:600}
/* precio original tachado cuando el código muerde */
.rb-fee-val s{color:var(--muted-2);font-weight:600;margin-right:6px}
.rb-payrow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:22px 2px}
.rb-payrow-label{font-size:19px;color:var(--ink)}
.rb-change{display:flex;align-items:center;gap:8px;background:none;border:none;cursor:pointer;font-family:inherit;font-size:18px;font-weight:700;color:var(--ink)}
.rb-change svg{color:var(--ink)}

.rb-foot{flex:none;padding:10px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.rb-book{width:100%;height:64px;border:none;border-radius:8px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;cursor:pointer;display:flex;align-items:center;justify-content:space-between;padding:0 26px;box-shadow:0 3px 6px rgba(0,0,0,.09)}
.rb-book-main{font-size:20px;font-weight:700}
.rb-book-cost{font-size:19px;font-weight:700}
.rb-book:active{filter:brightness(.96)}

/* ============ GENERIC BOTTOM SHEET (payment sheets) ============ */
.sheet-ov{position:absolute;inset:0;z-index:55;background:rgba(15,15,20,.44);display:flex;align-items:flex-end;opacity:0;transition:opacity .25s;pointer-events:auto}
.sheet-ov.show{opacity:1}
.sheet-pnl{width:100%;height:92%;background:#fff;border-radius:20px 20px 0 0;transform:translateY(100%);transition:transform .28s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column;overflow:hidden}
.sheet-ov.show .sheet-pnl{transform:translateY(0)}

/* --- Payment methods --- */
.pm-head{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:20px 18px 16px}
.pm-title{font-size:22px;font-weight:700;color:var(--ink)}
.pm-close{position:absolute;right:12px;top:16px;width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.pm-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:8px 20px 10px}
.pm-banner{background:#f3f3f5;border-radius:10px;padding:20px;text-align:center;font-size:20px;font-weight:700;color:var(--ink);margin-bottom:22px}
.pm-list{display:flex;flex-direction:column}
.pm-card{display:flex;align-items:center;gap:14px;width:100%;background:none;border:none;border-bottom:1px solid var(--border);cursor:pointer;font-family:inherit;text-align:left;padding:16px 2px}
.pm-card-ic{flex:none;color:var(--ink)}
.pm-card-label{flex:1;min-width:0;font-size:20px;color:var(--ink)}
.pm-card-edit{flex:none;color:var(--ink);display:flex;padding:4px}
.pm-card-check{flex:none;width:26px;color:var(--ink);display:flex;justify-content:flex-end}
.pm-addnew{display:flex;align-items:center;gap:8px;background:none;border:none;cursor:pointer;font-family:inherit;color:var(--ink);font-size:18px;font-weight:700;padding:20px 2px}
.pm-addnew svg{color:var(--ink)}
.pm-foot{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.pm-save{width:100%;height:60px;border:none;border-radius:8px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:20px;font-weight:700;cursor:pointer;box-shadow:0 3px 6px rgba(0,0,0,.09)}
.pm-save:active{filter:brightness(.96)}

/* --- Add a payment method --- */
.ac-head{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:20px 18px 16px}
.ac-title{font-size:22px;font-weight:700;color:var(--ink)}
.ac-close{position:absolute;right:12px;top:16px;width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.ac-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:20px 22px 10px}
.ac-field{display:flex;align-items:center;gap:12px;border-bottom:1px solid #d7d7db;padding:6px 0 12px}
.ac-field-ic{flex:none;color:#b7b7bd}
.ac-number{margin-bottom:44px}
.ac-input{flex:1;min-width:0;border:none;outline:none;background:none;font-family:inherit;font-size:22px;color:var(--ink)}
.ac-input::placeholder{color:#b7b7bd}
.ac-row{display:flex;gap:36px;margin-bottom:44px}
.ac-row .ac-field{flex:1}
.ac-save{width:100%;height:64px;border:none;border-radius:8px;background:#cbcbd0;color:#fff;font-family:inherit;font-size:20px;font-weight:600;cursor:not-allowed}
.ac-save.on{background:var(--ink);color:#fff;cursor:pointer}
.ac-save.on:active{filter:brightness(1.15)}
.ac-foot{flex:none;padding:18px 20px calc(20px + env(safe-area-inset-bottom,0px));display:flex;flex-direction:column;align-items:center;gap:12px}
.ac-logo-txt{background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.14em;padding:14px 10px;border-radius:3px}
.ac-powered{font-size:14px;font-weight:700;letter-spacing:.14em;color:var(--muted)}
.ac-brands{display:flex;align-items:center;gap:12px}
.ac-brand{width:60px;height:40px;border-radius:6px;display:flex;align-items:center;justify-content:center}
.ac-brand.visa{background:#1a1f71;color:#fff;font-size:16px;font-weight:800;font-style:italic;letter-spacing:.02em}
.ac-brand.ora{background:#fff;border:1px solid var(--border);color:#ff5a1f}
.ac-brand.mc{background:#26262a;gap:0}
.ac-brand.mc i{width:18px;height:18px;border-radius:50%;display:block}
.ac-brand.mc i:first-child{background:#eb001b;margin-right:-7px}
.ac-brand.mc i:last-child{background:#f79e1b;opacity:.9}

/* --- tarjeta REAL (Stripe Elements). Cada .ac-el hospeda un IFRAME de js.stripe.com: se le da
   ancho y alto propios porque el iframe no arrastra el alto del input que reemplazó. --- */
.ac-el{flex:1;min-width:0}
.ac-el .StripeElement{width:100%;padding:4px 0}
.ac-loading{font-size:15px;color:#b7b7bd}
.ac-consent{font-size:11.5px;line-height:1.5;color:var(--muted);margin:0 0 12px}
.ac-err{color:#df1b41;font-size:13px;min-height:18px;margin-bottom:10px}
.pm-empty{padding:18px 2px;font-size:17px;color:var(--muted);border-bottom:1px solid var(--border)}
/* botón de pagar mientras cobra: sin esto el socio vuelve a tocar y cree que no pasó nada */
.rp-purchase[disabled],.ct-pay-btn[disabled],.rb-book[disabled]{opacity:.6;cursor:default}

/* --- review booking: past-event warning --- */
.rb-past{display:flex;align-items:center;gap:12px;background:#fde8e8;border:1px solid #f2b8b8;border-radius:10px;padding:16px 16px;margin-bottom:16px}
.rb-past svg{flex:none;color:#e5484d}
.rb-past span{font-size:18px;color:var(--ink)}

/* ============ STUDIO CHECK-IN (barcode, from the Barcode pill) ============ */
.ci{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column;align-items:center}
.ci-back{position:absolute;left:10px;top:calc(env(safe-area-inset-top,0px) + 10px);width:46px;height:46px;border:none;background:none;color:#c4c4c8;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2}
.ci-head{flex:none;width:100%;text-align:center;padding:calc(env(safe-area-inset-top,0px) + 18px) 24px 0}
.ci-logo{display:flex;justify-content:center;margin-bottom:22px}
.ci-logo img{max-width:66px;max-height:66px;border-radius:8px}
.ci-logo-txt{width:66px;height:66px;border-radius:8px;background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.12em;display:flex;align-items:center;justify-content:center}
.ci-title{font-size:27px;font-weight:400;color:var(--ink);line-height:1.24}
.ci-code{flex:1;display:flex;align-items:center;justify-content:center;width:100%;padding:0 40px}
.ci-barcode,.ci-code .mg-barcode{width:300px;max-width:80%;height:150px;display:block}
.ci-nocode{text-align:center;font-size:17px;line-height:1.5;color:var(--muted);padding:0 30px}
.ci-qr{width:250px;max-width:74%;aspect-ratio:1/1;display:block}
.ci-qr svg{width:100%;height:100%;display:block}
.ci-mono{flex:none;font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:15px;letter-spacing:.2em;color:#8a8a90;padding:2px 24px 16px;text-align:center}
.ci-seg{flex:none;display:inline-flex;align-self:center;background:#f1f1f3;border-radius:12px;padding:4px;gap:4px;margin-bottom:8px}
.ci-segbtn{border:none;background:none;font:inherit;font-size:15px;font-weight:600;color:#8a8a90;padding:9px 28px;border-radius:9px;cursor:pointer;transition:background .15s}
.ci-segbtn.active{background:#fff;color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.12)}
.ci-sp{flex:none;height:40px}

/* ============ DATE PICKER (bottom sheet, from the Timetable calendar icon) ============ */
.dp-overlay{position:absolute;inset:0;z-index:55;background:rgba(15,15,20,.44);display:flex;align-items:flex-end;opacity:0;transition:opacity .25s;pointer-events:auto}
.dp-overlay.show{opacity:1}
.dp-sheet{width:100%;background:#fff;border-radius:22px 22px 0 0;transform:translateY(100%);transition:transform .28s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column;overflow:hidden}
.dp-overlay.show .dp-sheet{transform:translateY(0)}

.dp-head{flex:none;display:flex;align-items:center;justify-content:space-between;padding:22px 20px 14px}
.dp-title{font-size:24px;font-weight:700;color:var(--ink)}
.dp-close{width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center;margin:-8px -8px -8px 0}

.dp-monthbar{flex:none;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-top:1px solid var(--border)}
.dp-nav{width:44px;height:44px;border:none;background:none;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.dp-nav:active{opacity:.5}
.dp-month{flex:1;text-align:center;font-size:20px;font-weight:700;color:var(--ink)}

.dp-wd{display:grid;grid-template-columns:repeat(7,1fr);padding:4px 14px 2px}
.dp-wd span{text-align:center;font-size:16px;font-weight:600;color:#6d6d72}
.dp-grid{display:grid;grid-template-columns:repeat(7,1fr);row-gap:5px;padding:10px 14px 6px}
.dp-day{width:46px;height:46px;margin:0 auto;border:none;border-radius:50%;background:none;font-family:inherit;font-size:19px;font-weight:600;color:var(--ink);cursor:pointer;display:flex;align-items:center;justify-content:center}
.dp-day.today{box-shadow:inset 0 0 0 1.5px #d3d3d8}
.dp-day.sel{background:#111;color:#fff;font-weight:700;box-shadow:none}
/* Los días de RELLENO (los del mes vecino que completan la semana) van AL FINAL para ganarle
   siempre a .sel/.today: nunca deben verse circulados aunque el día coincida — si no, eliges
   el 26 de julio, te vas a agosto (donde el 26 sale de relleno en la semana del 1) y parece
   que sigue seleccionado. Mismo criterio para los días fuera del rango permitido. */
.dp-day.out,.dp-day.off{color:#cfcfd4;font-weight:500;cursor:default;background:none;box-shadow:none}

.dp-foot{flex:none;padding:14px 18px calc(16px + env(safe-area-inset-bottom,0px))}
.dp-go{width:100%;height:64px;border:none;border-radius:14px;background:var(--header);color:#fff;font-family:inherit;font-size:20px;font-weight:700;cursor:pointer}
.dp-go:active{filter:brightness(1.2)}

/* ============ PAYMENTS (from the profile Payments row) ============ */
.py{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.py-top{flex:none;background:var(--header);padding-top:max(env(safe-area-inset-top,0px), var(--statusbar))}
.py-bar{position:relative;display:flex;align-items:center;justify-content:center;height:56px;padding:0 16px}
.py-back{position:absolute;left:8px;top:50%;transform:translateY(-50%);width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.py-title{font-size:24px;font-weight:700;color:#fff}

.py-fixed{flex:none;background:#fff;padding:0 22px}
.py-card{display:flex;align-items:center;gap:14px;padding:22px 0 20px}
.py-card-ic{flex:none;color:var(--ink)}
.py-card-label{flex:1;min-width:0;font-size:23px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.py-replace{flex:none;border:none;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:17px;font-weight:700;padding:12px 18px;border-radius:8px;cursor:pointer}
.py-replace:active{filter:brightness(.96)}
.py-card-chev{flex:none;color:var(--ink);display:flex}
.py-hr{height:1px;background:var(--border)}
.py-h{font-size:30px;font-weight:800;color:var(--ink);padding:14px 0 16px}
.py-count{font-size:16px;font-weight:700;letter-spacing:.12em;color:#8c8c91;padding-bottom:14px}

.py-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
.py-loading{padding:26px;text-align:center;color:var(--muted);font-size:15px}
.py-item{display:flex;gap:14px;padding:22px 22px;border-bottom:1px solid var(--border)}
.py-item:nth-child(odd){background:#f6f6f7}
.py-when{flex:none;width:98px}
.py-when-date{font-size:16px;font-weight:600;color:#3f3f43;line-height:1.25}
.py-when-time{font-size:15px;color:var(--muted);margin-top:3px}
.py-desc{flex:1;min-width:0}
.py-desc-main{font-size:19px;font-weight:700;color:var(--ink);line-height:1.22}
.py-desc-sub{font-size:16px;color:var(--muted);margin-top:9px}
.py-desc-method{font-size:16px;color:var(--muted);margin-top:9px}
.py-amt{flex:none;font-size:20px;font-weight:700;color:var(--ink);white-space:nowrap;padding-top:1px}

/* ============ YOUR CREDITS (shell view from the profile Credits card) ============ */
.cx-hero{display:flex;flex-direction:column;align-items:center;gap:10px;padding:2px 0 22px}
.cx-badge{width:64px;height:64px;border-radius:50%;background:#d9d9dc;color:#26262a;display:flex;align-items:center;justify-content:center}
.cx-credits{font-size:20px;font-weight:700;color:#fff}

.cx-grid{display:grid;grid-template-columns:1fr 1fr;border-bottom:1px solid var(--border)}
.cx-cell{padding:18px 22px}
.cx-cell-l{border-right:1px solid var(--border)}
.cx-lbl{font-size:15px;font-weight:700;letter-spacing:.08em;color:#3b3b3f}
.cx-val{font-size:28px;font-weight:400;color:var(--ink);margin-top:12px;letter-spacing:-.01em}
.cx-valid{padding:18px 22px;border-bottom:1px solid var(--border)}
.cx-valid-v{font-size:20px;color:var(--ink);margin-top:16px}
.cx-book{display:block;margin:26px 22px 0;width:calc(100% - 44px);height:64px;border:1px solid #cfcfd4;border-radius:6px;background:#fff;font-family:inherit;font-size:20px;font-weight:700;color:var(--ink);cursor:pointer}
.cx-book:active{background:#fafafb}

/* ============ LOGIN / REGISTER (member auth) — refined & elegant ============ */
.lg{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column;
  padding:calc(env(safe-area-inset-top,0px) + 16px) 26px calc(18px + env(safe-area-inset-bottom,0px));
  overflow-y:auto;-webkit-overflow-scrolling:touch}

/* ============ LOGIN DEL GIMNASIO: foto + logo del CRM (orgs.data.login) ============
   Arriba la foto del gym con su logo encima; abajo una tarjeta que sube sobre la foto. Sin foto, el
   color de marca (--header) liso. El oscurecido sólo va con foto: cualquier foto puede tapar el logo. */
.lg.lg2{padding:0;background:#f7f7f3;
  /* LA LETRA DEL SISTEMA, como el diseño de Federico (SF Pro). No se descarga ni se incrusta (la
     licencia de Apple no lo permite): el iPhone ya la trae, y pidiendo la del sistema sale SF Pro
     exacta; en Android sale Roboto. Sólo en el login; el resto del app sigue en Rubik. */
  font-family:-apple-system,BlinkMacSystemFont,'SF Pro Text','SF Pro Display','Helvetica Neue',system-ui,sans-serif}
.lg.lg2 input,.lg.lg2 button{font-family:inherit}
.lg2-hero{position:relative;flex:none;height:clamp(220px,33vh,330px);background:var(--header) center/cover no-repeat;
  display:flex;align-items:center;justify-content:center;padding:env(safe-area-inset-top,0px) 32px 0}
.lg2-shade{position:absolute;inset:0;display:none;
  background:linear-gradient(180deg,rgba(0,0,0,.50) 0%,rgba(0,0,0,.28) 55%,rgba(0,0,0,.42) 100%)}
.lg2-hero.has-photo .lg2-shade{display:block}
.lg2-logo{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;width:100%;margin-bottom:24px}
.lg2-logo img{max-width:min(240px,70%);max-height:92px;object-fit:contain}
.lg2-logo.icono img{max-width:88px;max-height:88px;border-radius:20px;box-shadow:0 8px 24px -10px rgba(0,0,0,.6)}
.lg2-word{color:#fff;font-size:26px;font-weight:700;letter-spacing:.08em;text-align:center}
.lg2-card{position:relative;flex:1 0 auto;margin-top:-26px;background:#f7f7f3;border-radius:26px 26px 0 0;
  padding:30px 24px calc(env(safe-area-inset-bottom,0px) + 18px);display:flex;flex-direction:column}
.lg2-title{margin:0 0 22px;font-size:29px;font-weight:600;letter-spacing:-1.05px;line-height:1.13;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* nunca dos renglones (ver unRenglon) */
.lg2-form{gap:16px}
.lg2-label{font-size:14px;font-weight:500;color:#5b5b60}
.lg2-box{display:flex;align-items:center;height:54px;background:#fff;border:1px solid #e1e1dc;border-radius:14px;padding:0 16px}
.lg2-box:focus-within{border-color:var(--header)}
.lg2-eye{flex:none;display:flex;background:none;border:none;cursor:pointer;color:#8a8a90;padding:8px 0 8px 10px}
.lg2-forgot-row{display:flex;justify-content:flex-end;margin-top:-4px}
.lg2-forgot{background:none;border:none;cursor:pointer;font-family:inherit;font-size:14px;color:var(--ink);
  text-decoration:underline;text-underline-offset:3px;padding:2px 0}
.lg2-btn{height:54px;border:none;border-radius:14px;background:var(--header);color:#fff;font-family:inherit;
  font-size:17px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:10px}
.lg2-btn:active{filter:brightness(1.25)}
.lg2-btn:disabled{opacity:.55;cursor:default}
.lg2-faceid{margin-top:12px;height:54px;border:1px solid #dcdcd6;border-radius:14px;background:transparent;color:var(--ink);
  font-family:inherit;font-size:16px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:10px}
/* el hueco del botón: vacío no ocupa nada; con botón, es el botón a todo lo ancho */
.lg2-bio{display:flex;flex-direction:column}
.lg2-bio .lg2-faceid{width:100%}
.lg2-faceid:disabled{opacity:.55;cursor:default}

/* FACE ID: la hoja que lo ofrece (js/biometric.js). Va en <body>, encima de cualquier pantalla. */
.bio-veil{position:fixed;inset:0;z-index:500;background:rgba(12,12,14,.36);display:flex;align-items:flex-end;justify-content:center;
  opacity:0;transition:opacity .2s ease}
.bio-veil.on{opacity:1}
.bio-sheet{width:100%;max-width:480px;box-sizing:border-box;background:#fff;color:var(--ink);border-radius:22px 22px 0 0;
  padding:26px 22px calc(16px + env(safe-area-inset-bottom));text-align:center;font-family:inherit;
  transform:translateY(28px);transition:transform .24s ease}
.bio-veil.on .bio-sheet{transform:none}
/* la que pide contraseña (prender desde el perfil) va arriba: su campo abre el teclado */
.bio-veil.arriba{align-items:flex-start;padding:calc(env(safe-area-inset-top) + 56px) 12px 0}
.bio-veil.arriba .bio-sheet{border-radius:22px;padding-bottom:16px;transform:translateY(-20px)}
.bio-veil.arriba.on .bio-sheet{transform:none}
.bio-ic{width:54px;height:54px;margin:0 auto 14px;border-radius:16px;background:#f2f2ee;color:var(--ink);
  display:flex;align-items:center;justify-content:center}
.bio-t{margin:0 0 6px;font-size:19px;font-weight:600;letter-spacing:-.3px;line-height:1.25}
.bio-p{margin:0 auto 18px;max-width:300px;font-size:14px;line-height:1.45;color:#6b6b70}
.bio-pass{display:block;width:100%;box-sizing:border-box;height:48px;margin:0 0 14px;padding:0 14px;border:1px solid #dcdcd6;
  border-radius:12px;background:#fff;color:var(--ink);font-family:inherit;font-size:16px;outline:none}
.bio-pass:focus{border-color:var(--ink)}
.bio-err{margin:-6px 0 12px;font-size:13px;line-height:1.35;color:#e5352b}
.bio-err:empty{display:none}
.bio-yes{width:100%;height:50px;border:none;border-radius:14px;background:var(--header);color:#fff;font-family:inherit;
  font-size:16px;font-weight:600;cursor:pointer}
.bio-yes:disabled{opacity:.55;cursor:default}
.bio-no{width:100%;height:44px;margin-top:4px;border:none;background:none;font-family:inherit;font-size:15px;color:#6b6b70;cursor:pointer}
.bio-fine{margin:2px 0 0;font-size:12px;color:#9a9aa0}
.lg2-register{margin-top:22px;text-align:center;font-size:15px;color:#6b6b70}
.lg2-register button{background:none;border:none;cursor:pointer;font-family:inherit;font-size:15px;font-weight:700;color:var(--ink);padding:0 0 0 4px}
.lg2-foot{margin-top:auto;padding-top:18px;border-top:1px solid #e4e4df;display:flex;align-items:center;justify-content:center;
  gap:12px;font-size:14px;color:#6b6b70;min-height:20px}
.lg2-foot.two{justify-content:space-between}
.lg2-gymname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg2-change{flex:none;background:none;border:none;cursor:pointer;font-family:inherit;font-size:14px;font-weight:700;color:var(--ink);
  display:inline-flex;align-items:center;gap:2px;padding:0}
.lg-forgot{align-self:flex-end;background:none;border:none;cursor:pointer;font-family:inherit;font-size:16px;
  font-weight:600;color:var(--ink);text-decoration:underline;text-underline-offset:3px;padding:2px 0}
.lg-back{position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);left:10px;width:44px;height:44px;border:none;
  background:none;color:#111;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2}

.lg-logo{display:flex;justify-content:center;margin:24px 0 30px}
.lg-logo img{max-width:230px;max-height:120px;object-fit:contain}
.lg-logo-ph{display:flex;flex-direction:column;align-items:center;gap:9px;color:#111}
.lg-logo-mark{display:block}
.lg-logo-word{font-size:30px;font-weight:800;letter-spacing:.10em;color:#111}
.lg-logo-sub{font-size:11px;font-weight:600;letter-spacing:.34em;color:#111}

.lg-title{margin:0;font-size:27px;font-weight:700;color:var(--ink);letter-spacing:-.01em}
.lg-sub{margin:7px 0 26px;font-size:17px;font-weight:400;color:var(--muted)}

.lg-form{display:flex;flex-direction:column;gap:18px}
.lg-field{display:flex;flex-direction:column;gap:9px}
.lg-label{font-size:16px;font-weight:600;color:var(--ink)}
.lg-inputbox{display:flex;align-items:center;gap:12px;height:58px;border:1px solid #dcdce0;border-radius:14px;padding:0 16px}
.lg-inputbox:focus-within{border-color:#111}
.lg-inputbox > svg{flex:none;color:#9a9aa0}
.lg-input{flex:1;min-width:0;height:100%;border:none;background:none;outline:none;font-family:inherit;font-size:17px;color:var(--ink)}
.lg-input::placeholder{color:#a3a3a9}
.lg-show{flex:none;background:none;border:none;cursor:pointer;font-family:inherit;font-size:16px;color:var(--muted);padding:0 0 0 8px}
.lg-help{font-size:15px;line-height:1.45;color:var(--muted);margin-top:2px}

/* ---- alta en PASOS (estilo Glofox): campos de línea, fecha DD/MM/YYYY, consentimientos ---- */
.lg-line{
  width:100%;border:none;border-bottom:1px solid #d5d5d8;background:none;outline:none;
  font-family:inherit;font-size:20px;color:var(--ink);padding:14px 2px 10px;
}
.lg-line:focus{border-bottom-color:#111}
.lg-line::placeholder{color:#c3c3c8}
.lg-dob{display:flex;gap:16px}
.lg-dob .dob{flex:1;letter-spacing:.05em}
.lg-dob .dob.yyyy{flex:1.4}
.rg .lg-label{font-size:15px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink)}
.rg .lg-field{margin-bottom:26px}
.rg-next{position:relative}
.rg-next svg{position:absolute;right:20px;color:#fff}
.rg-card{background:#f6f6f7;border-radius:14px;padding:22px 18px}
.rg-q{margin:0 0 18px;font-size:21px;font-weight:700;color:var(--ink);line-height:1.25}
.rg-check{display:flex;align-items:flex-start;gap:14px;padding:10px 0;cursor:pointer}
.rg-check input{position:absolute;opacity:0;pointer-events:none}
.rg-box{
  flex:none;width:26px;height:26px;border:1.5px solid #b9b9be;border-radius:6px;background:#fff;
  display:flex;align-items:center;justify-content:center;color:transparent;margin-top:2px;
}
.rg-check input:checked + .rg-box{border-color:#1a8f3c;color:#1a8f3c}
.rg-txt{flex:1;font-size:16px;line-height:1.4;color:var(--text)}
.rg-legal{margin:20px 2px 0;font-size:16px;color:var(--text)}
.rg-legal b{color:var(--ink)}
.lg-err{min-height:18px;font-size:15px;color:#e5352b;text-align:center;line-height:1.35}
.lg-err.info{color:var(--muted)}
/* botón del mensaje de migración: discreto, no compite con "Log In" */
.lg-mig{margin-top:8px;background:none;border:none;cursor:pointer;font-family:inherit;
  font-size:15px;font-weight:600;color:var(--ink);text-decoration:underline;padding:4px}
.lg-mig:disabled{color:var(--muted);text-decoration:none;cursor:default}

/* Forgot your password (views/forgot.js) — reusa .lg-* del login; sólo lo suyo va aquí */

/* ── FIND YOUR GYM (app madre) ───────────────────────────────────────────────────────────────
   La única pantalla de MODO.PULSE: en cuanto el socio mete su código, todo lo demás se pinta con
   la marca de SU gimnasio. Por eso NO reusa el formulario blanco del login —ahí ya manda el gym—.
   El verde es el del icono de la app (#01b37f), no uno inventado. */
.gc{position:absolute;inset:0;background:#0e0f10;overflow:hidden;display:flex;flex-direction:column}
/* La onda. Va en el verde de marca muy bajado: a todo color se come la pantalla y el protagonista
   es el nombre, no el adorno. */
.gc-wave{position:absolute;top:0;left:0;width:100%;height:150px;pointer-events:none}
.gc-wave path{fill:#0d3b2c}
.gc-body{position:relative;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  display:flex;flex-direction:column;padding:0 28px calc(24px + env(safe-area-inset-bottom,0px));
  padding-top:max(calc(env(safe-area-inset-top,0px) + 150px), 180px)}
/* La firma: EL LOGO, no el nombre tecleado. Va con alto fijo y ancho automático para que no se
   deforme si algún día cambia la proporción del archivo. */
.gc-brand{display:block;height:34px;width:auto;margin:0 auto 46px}
.gc-form{display:flex;flex-direction:column}
.gc-hint{text-align:center;font-size:15px;color:#8d9095;margin-bottom:14px}
/* SUBRAYADO, no caja: un código de 8 dígitos se teclea, no se "llena". Es la diferencia entre
   una pantalla de producto y un formulario cualquiera. */
.gc-line{display:flex;align-items:center;gap:12px;border-bottom:1px solid #35383c;padding:0 2px 12px}
.gc-line:focus-within{border-bottom-color:#01b37f}
.gc-line > svg{flex:none;color:#6c7076}
.gc-code{flex:1;min-width:0;border:none;background:none;outline:none;font-family:inherit;
  font-size:24px;font-weight:600;letter-spacing:.14em;color:#fff;padding:0}
.gc-code::placeholder{color:#44474b;letter-spacing:.14em;font-weight:500}
.gc-err{min-height:20px;font-size:14px;color:#ff6b63;margin-top:12px}
.gc-btn{height:56px;border:none;border-radius:14px;background:#01b37f;color:#04150f;
  font-family:inherit;font-size:17px;font-weight:700;cursor:pointer;margin-top:10px}
.gc-btn:active{filter:brightness(1.12)}
.gc-btn:disabled{opacity:.45;cursor:default}
.gc-help{font-size:13px;line-height:1.5;color:#75797f;margin:16px 0 0}
.gc-center{text-align:center}
.gc-again{background:none;border:none;cursor:pointer;font-family:inherit;font-size:15px;
  font-weight:600;color:#8d9095;padding:18px 0 0}
.gc-back{position:absolute;top:calc(env(safe-area-inset-top,0px) + 10px);left:10px;z-index:2;
  width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;
  display:flex;align-items:center;justify-content:center}
/* El gimnasio encontrado: su marca en grande, sobre el lienzo de la plataforma. */
.gc-found{display:flex;flex-direction:column;align-items:center;gap:10px;margin-bottom:8px}
.gc-logo{width:84px;height:84px;border-radius:24px;background:#17191c;color:#9aa0a6;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.gc-logo img{width:100%;height:100%;object-fit:contain}
.gc-name{font-size:24px;font-weight:700;color:#fff;text-align:center;line-height:1.2}
.gc-city{font-size:15px;color:#8d9095}

.fg-mark{width:58px;height:58px;border-radius:17px;background:#f2f2f6;color:var(--ink);
  display:flex;align-items:center;justify-content:center;margin:0 0 18px}
.fg-note{margin-top:20px}
/* "Send it again": secundario a propósito, el botón negro es "Back to log in" */
.lg-again{margin-top:14px;background:none;border:none;cursor:pointer;font-family:inherit;
  font-size:16px;font-weight:600;color:var(--ink);text-decoration:underline;padding:6px}
.lg-again:disabled{color:var(--muted);text-decoration:none;cursor:default}

/* Set your password — las 5 reglas se marcan mientras escribe (mismas que el CRM) */
.sp-rules{list-style:none;margin:2px 0 0;padding:0;display:flex;flex-direction:column;gap:7px}
.sp-rules li{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--muted);transition:color .16s}
.sp-rules li.on{color:#1b9e58}
.sp-dot{width:16px;height:16px;flex:none;border-radius:50%;border:1.5px solid currentColor;
  display:flex;align-items:center;justify-content:center;font-size:10px;line-height:1;transition:background .16s,border-color .16s}
.sp-rules li.on .sp-dot{background:#1b9e58;border-color:#1b9e58;color:#fff}

.lg-btn{height:58px;border:none;border-radius:14px;background:#111;color:#fff;font-family:inherit;font-size:18px;font-weight:700;cursor:pointer;margin-top:2px}
.lg-btn:active{filter:brightness(1.9)}
.lg-btn:disabled{opacity:.55;cursor:default}

.lg-or{display:flex;align-items:center;gap:16px;margin:24px 0}
.lg-or-line{flex:1;height:1px;background:var(--border)}
.lg-or-txt{font-size:14px;font-weight:600;letter-spacing:.06em;color:var(--muted)}

.lg-faceid{display:flex;align-items:center;justify-content:center;gap:12px;height:58px;border:1px solid #dcdce0;border-radius:14px;
  background:#fff;cursor:pointer;font-family:inherit;font-size:18px;font-weight:700;color:var(--ink)}
.lg-faceid:active{background:#fafafb}
.lg-faceid > svg{flex:none;color:#111}

.lg-register{margin-top:auto;padding-top:26px;text-align:center;font-size:17px;color:var(--muted)}
.lg-register button{display:inline-flex;align-items:center;gap:3px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:17px;font-weight:700;color:var(--ink);padding:0 0 0 6px}
.lg-register button > svg{color:var(--ink)}
/* app madre instalada: el gimnasio elegido y "Change gym" (sin cuenta) */
.lg-gym{padding-top:14px;display:flex;align-items:center;justify-content:center;gap:8px;font-size:15px;color:var(--muted)}
.lg-gym-name{max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg-gym button{background:none;border:none;cursor:pointer;font-family:inherit;font-size:15px;font-weight:700;
  color:var(--ink);padding:0;text-decoration:underline;text-underline-offset:3px}

/* ============ MY PROGRESS (from profile My visits / Track your progress) ============ */
.pg{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.pg-top{flex:none;background:var(--header);padding-top:max(env(safe-area-inset-top,0px), var(--statusbar))}
.pg-bar{position:relative;display:flex;align-items:center;justify-content:center;height:56px;padding:0 16px}
.pg-back{position:absolute;left:8px;top:50%;transform:translateY(-50%);width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.pg-title-top{font-size:24px;font-weight:700;color:#fff}

.pg-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:18px 20px 16px}

/* Las pestañas de periodo. Se queda la píldora que ya existía (es la del resto de la app). */
.pg-tabs{display:flex;background:#f1f1f3;border-radius:30px;padding:5px;margin-bottom:22px}
.pg-tab{flex:1;border:none;background:none;cursor:pointer;font-family:inherit;font-size:15px;
  font-weight:600;color:#6d6d72;padding:11px 0;border-radius:24px;white-space:nowrap}
.pg-tab.on{background:#111;color:#fff}
/* La fila de navegación: ← mes → . Los topes se APAGAN, no se esconden — un botón que
   desaparece recorre la fila entera de lugar justo cuando llegas al borde. */
.pg-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px}
.pg-period{flex:1;text-align:center;font-size:15px;font-weight:600;color:var(--ink)}
.pg-arrow{flex:none;width:36px;height:36px;border:1px solid var(--border);border-radius:50%;
  background:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#55555c}
.pg-arrow:disabled{opacity:.3;cursor:default}

/* LA TARJETA. Mismo lenguaje que la de membresía en el perfil: oscura, el número en grande y
   el detalle en voz baja debajo. */
.pg-hero{border-radius:18px;background:#1e2a1e;color:#fff;padding:20px;margin-bottom:22px}
.pg-hero-h{font-size:16px;font-weight:700;color:#fff}
.pg-big{font-size:58px;font-weight:800;line-height:1;letter-spacing:-.03em;color:#cfe9b0;margin-top:14px}
.pg-big-sub{font-size:14px;color:rgba(255,255,255,.62);margin-top:8px}
.pg-track{height:8px;border-radius:5px;background:rgba(255,255,255,.16);margin-top:18px;overflow:hidden}
.pg-fill{height:100%;border-radius:5px;background:#cfe9b0;transition:width .25s ease}
.pg-foot-txt{font-size:14px;color:rgba(255,255,255,.72);margin-top:12px}
.pg-foot-txt b{color:#fff;font-weight:700}

/* Las dos cifras de abajo: etiqueta a la izquierda, número a la derecha. */
.pg-stat{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px 2px;border-bottom:1px solid var(--border)}
.pg-stat:last-child{border-bottom:none}
.pg-stat span{font-size:16px;color:var(--text)}
.pg-stat b{font-size:20px;font-weight:700;color:var(--ink);text-align:right}
.pg-empty{font-size:15px;color:var(--muted);line-height:1.5;margin:8px 0}

.pg-foot{flex:none;padding:10px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.pg-book{width:100%;display:flex;align-items:center;gap:12px;background:#1e2a1e;border:none;
  border-radius:14px;padding:18px;cursor:pointer;font-family:inherit;font-size:17px;font-weight:700;color:#fff}
.pg-book > span{flex:1;text-align:left}
.pg-book svg{flex:none;color:#cfe9b0}

/* ============ BOOKED! (booking confirmation) ============ */
.bk2{position:absolute;inset:0;background:var(--header);display:flex;flex-direction:column;overflow:hidden}
.bk2-banner{flex:none;display:flex;align-items:center;gap:12px;background:#7fd90f;
  padding:calc(env(safe-area-inset-top,0px) + 12px) 16px 14px;transition:margin-top .25s ease, opacity .25s ease}
/* El -180px que había aquí era un número inventado: el aviso mide lo que mida el nombre de la
   clase (se parte en 2 o 3 renglones) más el notch, así que unas veces se iba de más y otras se
   quedaba a medias — y en ambos casos el contenido de abajo se recorría. La altura real la mide
   el JS al cerrarlo (ver booked.js) y la pone en style.marginTop. */
.bk2-banner.hide{opacity:0}
.bk2-banner-ic{flex:none;color:#123400;display:flex}
.bk2-banner-txt{flex:1;min-width:0;font-size:17px;font-weight:600;line-height:1.25;color:#123400}
.bk2-banner-x{flex:none;background:none;border:none;color:#123400;cursor:pointer;display:flex;padding:2px}

.bk2-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
.bk2-white{background:#fff;padding:22px 20px;text-align:center}
.bk2-logo{display:flex;justify-content:center;margin-bottom:14px}
.bk2-logo img{max-width:72px;max-height:72px}
.bk2-logo-txt{background:#111;color:#fff;font-size:9px;font-weight:700;letter-spacing:.14em;padding:16px 12px;border-radius:3px}
.bk2-title{margin:4px 0 22px;font-size:42px;font-weight:800;color:var(--ink);letter-spacing:-.015em}
.bk2-hero{height:210px;border-radius:14px;background:#1a1a1c center/cover no-repeat;display:flex;align-items:center;justify-content:center;color:#3a3a3c}
.bk2-info{display:flex;flex-direction:column;align-items:flex-start;text-align:left;padding:18px 2px 4px}
.bk2-name{font-size:30px;font-weight:800;color:var(--ink)}
.bk2-when{display:flex;align-items:center;gap:14px;margin-top:12px}
.bk2-when-ic{width:44px;height:44px;flex:none;border-radius:50%;background:#eeeef0;color:#565660;display:flex;align-items:center;justify-content:center}
.bk2-when-date{display:block;font-size:18px;color:var(--muted)}
.bk2-when-time{display:block;font-size:20px;font-weight:700;color:var(--ink);margin-top:2px}

.bk2-actions{display:flex;gap:14px;margin-top:24px}
.bk2-act{flex:1;display:flex;align-items:center;justify-content:center;gap:10px;height:58px;border:none;border-radius:12px;
  background:#7fd90f;color:#0f2a00;font-family:inherit;font-size:17px;font-weight:700;cursor:pointer}
.bk2-act:active{filter:brightness(.95)}
.bk2-act svg{flex:none;color:#0f2a00}

.bk2-foot{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.bk2-browse{width:100%;height:60px;border:none;border-radius:10px;background:var(--btn-gray);color:var(--btn-gray-ink);
  font-family:inherit;font-size:19px;font-weight:700;cursor:pointer}
.bk2-browse:active{filter:brightness(.96)}
.bk2-spot{display:inline-block;margin-top:12px;background:#e6f4ea;color:#1a8f3c;font-size:16px;font-weight:700;padding:6px 14px;border-radius:14px}

/* ============ SPOT PICKER (seat map booking) ============ */
.sp{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.sp-top{flex:none;background:var(--header);padding-top:max(env(safe-area-inset-top,0px), var(--statusbar))}
.sp-bar{position:relative;display:flex;align-items:center;justify-content:center;height:56px;padding:0 16px}
.sp-back{position:absolute;left:8px;top:50%;transform:translateY(-50%);width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.sp-title{font-size:22px;font-weight:700;color:#fff}
/* fixed chrome: class + legend + FRONT/COACH bar stay put; only the map scrolls */
.sp-head{flex:none;padding:20px 20px 16px}
.sp-class{text-align:center;margin-bottom:16px}
.sp-class-name{font-size:26px;font-weight:800;color:var(--ink)}
.sp-class-sub{font-size:16px;color:var(--muted);margin-top:5px}
.sp-legend{display:flex;justify-content:center;gap:24px;margin-bottom:16px}
.sp-leg{display:inline-flex;align-items:center;gap:8px;font-size:15px;color:var(--text)}
.sp-dot{width:16px;height:16px;border-radius:5px;display:inline-block}
.sp-dot.avail{background:#fff;border:1.5px solid #cfcfd4}
.sp-dot.taken{background:#dcdce0}
.sp-dot.sel{background:#1a8f3c}
.sp-stage{text-align:center;font-size:13px;font-weight:700;letter-spacing:.14em;color:var(--muted);background:#f1f1f3;border-radius:8px;padding:11px}
/* the map: scrolls in whatever direction it needs; centers when it fits */
.sp-gridwrap{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch}
/* margin:auto centers when it fits but (unlike justify-content:center) stays scrollable to BOTH ends when it overflows */
.sp-gridpad{box-sizing:border-box;min-width:100%;min-height:100%;display:flex;padding:18px 20px}
.sp-loading,.sp-empty{text-align:center;color:var(--muted);font-size:15px;padding:30px;margin:auto}
.sp-grid{display:grid;gap:12px;grid-auto-rows:var(--sp-cell);margin:auto}
:root{--sp-cell:70px}
.sp-cell{width:var(--sp-cell);height:var(--sp-cell);border-radius:12px;display:flex;align-items:center;justify-content:center;font-family:inherit}
.sp-cell.spot{background:#fff;border:1.5px solid #cfcfd4;color:var(--ink);font-size:16px;font-weight:700;cursor:pointer}
.sp-cell.spot:active{background:#f4f4f5}
.sp-cell.spot.sel{background:#1a8f3c;border-color:#1a8f3c;color:#fff}
.sp-cell.taken{background:#e4e4e7;color:#a8a8ae;font-size:16px;font-weight:700;cursor:not-allowed}
.sp-cell.feature{background:#e7e7ea;color:#6d6d72;font-size:11px;font-weight:700;letter-spacing:.05em}
.sp-cell.empty{visibility:hidden}
.sp-foot{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.sp-book{width:100%;height:60px;border:none;border-radius:12px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:19px;font-weight:700;cursor:pointer}
.sp-book:disabled{background:#ededee;color:#b8b8bd;cursor:not-allowed}
.sp-book:active:not(:disabled){filter:brightness(.96)}

/* ============ DOCUMENTS + FIRMA ELECTRÓNICA ============ */
/* badge rojo: en la fila del perfil y en el avatar del header */
.pf-row-badge{display:none}
.pf-row-badge.on{
  display:flex;align-items:center;justify-content:center;flex:none;
  min-width:24px;height:24px;padding:0 7px;border-radius:12px;margin-right:10px;
  background:#f2e3b8;color:#5b4713;font-size:12px;font-weight:600;white-space:nowrap;
}
/* OJO: aquí NO se toca `position` — el ancla la pone .tb-avatar arriba, que hoy es una CELDA de
   grid con `position:relative` puesto a propósito. (Antes el avatar era `absolute` y por eso ya
   servía de referencia solo; se cambió a grid para que un nombre de gimnasio largo no se meta
   debajo de la bolita.) Si aquí se declara cualquier `position`, el badge se despega. */
.tb-avatar-badge{display:none}
.tb-avatar-badge.on{
  display:flex;align-items:center;justify-content:center;
  position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;
  border-radius:10px;background:#ff5a5f;color:#fff;font-size:12px;font-weight:700;
  border:2px solid var(--header);
}

.dc{position:absolute;inset:0;background:#fff;display:flex;flex-direction:column}
.dc-top{flex:none;background:var(--header);padding-top:max(env(safe-area-inset-top,0px), var(--statusbar))}
.dc-bar{position:relative;display:flex;align-items:center;justify-content:center;height:56px;padding:0 16px}
.dc-back{position:absolute;left:8px;top:50%;transform:translateY(-50%);width:44px;height:44px;border:none;background:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.dc-title{font-size:24px;font-weight:700;color:#fff}
.dc-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
.dc-loading{padding:26px;text-align:center;color:var(--muted);font-size:15px}

.dc-list{padding:4px 0}
.dc-row{display:flex;align-items:center;gap:12px;width:100%;background:none;border:none;border-bottom:1px solid var(--border);
  cursor:pointer;font-family:inherit;text-align:left;padding:20px 18px}
.dc-row:active{background:#fafafb}
.dc-row-main{flex:1;min-width:0;display:flex;flex-direction:column}
.dc-row-name{font-size:20px;color:var(--ink)}
.dc-row-sub{font-size:16px;color:var(--muted);margin-top:4px}
.dc-row > svg{flex:none;color:#c2c2c8}
.dc-badge{flex:none;width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:#fff}
.dc-badge.ok{background:#3ddc97}
.dc-badge.bad{background:#ff7a7d}

/* detalle */
.dcd{background:#fff}
.dcd-head{flex:none;position:relative;display:flex;align-items:center;justify-content:center;padding:calc(env(safe-area-inset-top,0px) + 14px) 56px 14px;border-bottom:1px solid var(--border)}
.dcd-title{font-size:21px;font-weight:700;color:var(--ink);text-align:center}
.dcd-x{position:absolute;right:10px;top:calc(env(safe-area-inset-top,0px) + 10px);width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.dcd-meta{padding:4px 18px}
.dcd-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 0;border-bottom:1px solid var(--border);font-size:18px;color:var(--muted)}
.dcd-status{display:inline-flex;align-items:center;gap:10px;color:var(--ink)}
.dcd-status.bad{color:var(--ink)}
.dcd-warn{color:#ff7a7d}
.dcd-doc{margin:18px;padding:20px 18px;background:#f4f4f5;border-radius:12px;font-size:17px;line-height:1.5;color:var(--ink);overflow-wrap:anywhere}
.dcd-doc h3{font-size:19px;margin:18px 0 8px}
.dcd-doc p{margin:0 0 10px}
.dcd-doc ul{padding-left:20px;margin:0 0 10px}
.dc-sig-slot{display:inline-block;border:1.5px dashed #ff7a7d;color:#ff5a5f;border-radius:6px;padding:4px 12px;font-size:15px;font-weight:600}
.dc-sig-img{display:block;max-width:230px;max-height:80px;margin:6px 0}
.dcd-foot{flex:none;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px));background:#fff}
.dcd-sign{width:100%;height:60px;border:none;border-radius:10px;background:var(--btn-gray);color:var(--btn-gray-ink);font-family:inherit;font-size:19px;font-weight:700;cursor:pointer}
.dcd-sign:active{filter:brightness(.96)}

/* hoja de firma */
.sg{height:auto;max-height:94%}
.sg-head{flex:none;position:relative;display:flex;align-items:center;padding:20px 18px 10px}
.sg-title{font-size:24px;font-weight:700;color:var(--ink)}
.sg-x{position:absolute;right:12px;top:14px;width:44px;height:44px;border:none;background:none;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.sg-tabs{flex:none;display:flex;gap:26px;padding:0 18px;border-bottom:1px solid var(--border)}
.sg-tab{background:none;border:none;cursor:pointer;font-family:inherit;font-size:19px;color:var(--muted);padding:10px 0 12px;border-bottom:2px solid transparent}
.sg-tab.on{color:var(--ink);font-weight:700;border-bottom-color:#1a8f3c}
.sg-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:18px}
.sg-pad{background:#f4f4f5;border-radius:10px;padding:16px}
.sg-padtop{display:flex;align-items:center;gap:12px}
.sg-font,.sg-clear{background:none;border:none;cursor:pointer;font-family:inherit;font-size:17px;color:var(--muted);display:inline-flex;align-items:center;gap:6px;padding:0}
.sg-clear{display:none}
.sg.is-draw .sg-font{display:none}
.sg.is-draw .sg-clear{display:inline-flex}
.sg-colors{margin-left:auto;display:flex;gap:12px}
.sg-color{width:30px;height:30px;border-radius:50%;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;color:transparent}
.sg-color.on{color:#fff}
.sg-stage{position:relative;height:150px;margin-top:10px}
.sg-typed{position:absolute;inset:0;width:100%;border:none;background:none;outline:none;text-align:center;font-size:40px;color:var(--ink);padding:0 10px}
.sg-canvas{position:absolute;inset:0;width:100%;height:100%;display:none;touch-action:none}
.sg.is-draw .sg-typed{display:none}
.sg.is-draw .sg-canvas{display:block}
.sg-line{position:absolute;left:14px;right:14px;bottom:26px;height:1px;background:#cfcfd4}
.sg-legal{margin:16px 2px 0;font-size:16px;line-height:1.45;color:var(--muted)}
.sg-warn{min-height:20px;margin-top:12px;font-size:16px;line-height:1.4;color:#8a6d3b;background:#fdf6e3;border-radius:8px}
.sg-warn:not(:empty){padding:12px 14px}
.sg-foot{flex:none;display:flex;gap:14px;padding:12px 16px calc(14px + env(safe-area-inset-bottom,0px))}
.sg-cancel{flex:0 0 34%;height:58px;border:none;border-radius:10px;background:#f1f1f3;color:var(--ink);font-family:inherit;font-size:18px;font-weight:600;cursor:pointer}
.sg-accept{flex:1;height:58px;border:none;border-radius:10px;background:#1a8f3c;color:#fff;font-family:inherit;font-size:18px;font-weight:700;cursor:pointer}
.sg-accept:active{filter:brightness(1.1)}

/* profile sign-out */
.pf-signout{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;margin-top:26px;
  background:none;border:none;cursor:pointer;font-family:inherit;color:#e5352b;font-size:19px;font-weight:700;padding:8px}
.pf-signout svg{color:#e5352b}
/* Borrado de cuenta: se ve, pero no invita. Chiquito y gris — no es una acción que promovamos,
   y las tiendas sólo exigen que sea ENCONTRABLE, no que compita con Sign out. */
.pf-delete{display:block;width:100%;margin:18px 0 4px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:14px;font-weight:500;color:#8b8fa3;padding:8px;text-decoration:underline}
/* la versión del build: discreta, pero legible sin lupa — es para leerla en voz alta por teléfono */
.pf-version{text-align:center;font-size:12px;color:#a8abbb;padding:6px 0 2px;letter-spacing:.04em;cursor:pointer}
.pf-version.on{color:#e5352b;font-weight:700}
/* Contador de gestos. NO es para el socio: se enciende tocando la versión en el perfil, y sirve
   para que el TELÉFONO diga qué eventos le llegan de verdad — algo que ningún evento sintético en
   el escritorio puede reproducir. Va arriba, fuera del camino del pulgar. */
.gest-hud{position:absolute;left:8px;right:8px;top:calc(env(safe-area-inset-top,0px) + 4px);
  z-index:70;pointer-events:none;background:rgba(10,10,12,.86);color:#7fd90f;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.45;
  padding:6px 9px;border-radius:8px;white-space:pre-wrap;text-align:left}

/* ---- pantalla de borrado de cuenta ---- */
.da{display:flex;flex-direction:column;height:100%;background:#fff}
.da-top{display:flex;align-items:center;gap:8px;padding:14px 12px 10px;border-bottom:1px solid #eceaf3}
.da-top-title{font-size:15px;font-weight:500;color:var(--ink,#1c1b39)}
.da-scroll{flex:1;overflow-y:auto;padding:22px 20px 8px}
.da-title{margin:0 0 8px;font-size:24px;font-weight:600;letter-spacing:-.01em;color:var(--ink,#1c1b39)}
.da-lead{margin:0 0 22px;font-size:15px;line-height:1.55;color:#5b5f7b}
.da-block{border:1px solid #eceaf3;border-radius:12px;padding:14px 16px;margin-bottom:14px}
.da-block-h{font-size:12px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:#8b8fa3;margin-bottom:9px}
.da-list{margin:0;padding-left:18px}
.da-list li{font-size:14px;line-height:1.6;color:var(--ink,#1c1b39);margin-bottom:3px}
.da-note{margin:10px 0 0;font-size:13px;line-height:1.55;color:#8b8fa3}
.da-confirm-l{display:block;margin:22px 0 8px;font-size:14px;color:#5b5f7b}
.da-confirm-l b{font-weight:600;color:var(--ink,#1c1b39)}
.da-confirm{width:100%;box-sizing:border-box;padding:13px 14px;border:1px solid #dcdae8;border-radius:10px;
  font-family:inherit;font-size:16px;letter-spacing:.08em;color:var(--ink,#1c1b39);background:#fff}
.da-confirm:focus{outline:none;border-color:#b9b5d6}
.da-err{margin-top:10px;font-size:13px;line-height:1.5;color:#e5352b;min-height:1px}
.da-err a{color:#e5352b}
.da-foot{padding:12px 20px 22px;border-top:1px solid #eceaf3}
.da-go{width:100%;padding:15px;border:none;border-radius:10px;cursor:pointer;font-family:inherit;
  font-size:16px;font-weight:600;color:#fff;background:#e5352b}
.da-go:disabled{background:#eceaf3;color:#b0b3c4;cursor:default}
.da-cancel{width:100%;margin-top:6px;padding:12px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:15px;font-weight:500;color:#5b5f7b}

/* ---- access check (diagnóstico de RLS; no es producto) ---- */
.ac{display:flex;flex-direction:column;height:100%;background:#fff}
.ac-scroll{flex:1;overflow-y:auto;padding:16px 16px 30px}
.ac-who{font-size:13px;line-height:1.6;color:#5b5f7b;margin-bottom:14px}
.ac-who code{font-size:12px;color:var(--ink,#1c1b39)}
.ac-sum{padding:12px 14px;border-radius:10px;font-size:14px;line-height:1.5;margin-bottom:16px;font-weight:500}
.ac-sum.ok{background:#e9f7ef;color:#0f7a45}
.ac-sum.bad{background:#fdecea;color:#b3261e}
.ac-sum.run{background:#f4f4f8;color:#5b5f7b}
.ac-row{border-bottom:1px solid #eceaf3;padding:11px 0}
.ac-row-h{display:flex;align-items:center;justify-content:space-between;gap:10px}
.ac-lbl{font-size:14.5px;color:var(--ink,#1c1b39);display:flex;align-items:center;gap:7px}
.ac-lvl{font-style:normal;font-size:10.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  padding:2px 6px;border-radius:5px}
.ac-lvl.own{background:#eef0fb;color:#3a3690}
.ac-lvl.public{background:#f4f4f8;color:#8b8fa3}
.ac-lvl.never{background:#fdecea;color:#b3261e}
.ac-pill{font-size:12.5px;font-weight:600;padding:3px 9px;border-radius:20px;white-space:nowrap}
.ac-pill.ok{background:#e9f7ef;color:#0f7a45}
.ac-pill.bad{background:#fdecea;color:#b3261e}
.ac-pill.warn{background:#fff5e5;color:#96601a}
.ac-pill.run{background:#f4f4f8;color:#8b8fa3}
.ac-note{margin:5px 0 0;font-size:12.5px;line-height:1.5;color:#8b8fa3}
.ac-note.err{color:#b3261e}

/* ============================================================================
   SCROLL DE LADO — que NINGUNA pantalla se mueva horizontalmente
   ============================================================================
   Trampa de CSS, no descuido: cuando `overflow-y` es `auto` y `overflow-x` se queda en `visible`,
   la especificación obliga al navegador a computar `overflow-x` como `auto`. Es decir, TODO
   contenedor con scroll vertical trae scroll horizontal de regalo, y basta un título largo o una
   palabra que no quepa para que la pantalla se recorra de lado (lo cazó Federico en el detalle de
   clase: "HYROX PERMANENTE" mide 455px en una pantalla de 430).

   Va como regla agrupada y no repartida en 21 declaraciones para que se lea de un golpe y para que
   la pantalla nueva sepa que tiene que sumarse aquí. Los scrollers que SÍ son horizontales a
   propósito (la tira de fechas, el pager de Memberships/Bookings, el mapa de asientos) declaran su
   `overflow-x:auto` explícito y no están en esta lista. */
.view, .cd-scroll, .pf-scroll, .cp-scroll, .pd-scroll, .co-scroll, .ct-scroll, .mp-scroll,
.rp-scroll, .rb-body, .pm-body, .ac-body, .py-scroll, .pg-scroll, .bk2-scroll, .dc-scroll,
.sg-body, .da-scroll, .ac-scroll, .bk-page, .pgr-page{
  overflow-x:hidden;
}

/* ---- visor de foto (Tap to zoom del producto) ---- */
.zoomv{position:absolute;inset:0;background:#000;display:flex;flex-direction:column}
.zoomv-x{position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);right:12px;z-index:3;
  width:46px;height:46px;border-radius:50%;border:none;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;display:flex;align-items:center;justify-content:center}
.zoomv-stage{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;overflow:hidden;
  /* el gesto lo maneja el JS: sin esto el navegador se lleva el arrastre y el pellizco no responde */
  touch-action:none}
.zoomv-stage img{max-width:100%;max-height:100%;object-fit:contain;transform-origin:center center;
  will-change:transform;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}
.zoomv-dots{flex:none;display:flex;justify-content:center;gap:8px;
  padding:14px 0 calc(env(safe-area-inset-bottom,0px) + 18px)}
.zoomv-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.32);cursor:pointer}
.zoomv-dot.on{background:#fff}

/* ============================ EDIT PROFILE ============================ */
.pe{position:absolute;inset:0;display:flex;flex-direction:column;background:#fff}
.pe-top{flex:none;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:calc(env(safe-area-inset-top,0px) + 8px) 12px 10px;border-bottom:1px solid #eceaf3}
.pe-logo{grid-column:2;display:flex;align-items:center;justify-content:center;height:44px}
.pe-logo img{max-height:44px;max-width:120px;object-fit:contain}
.pe-logo-txt{font-size:13px;font-weight:700;letter-spacing:.08em;color:var(--ink,#1c1b39)}
.pe-top-sp{grid-column:3}
.pe-scroll{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;padding:18px 20px 8px}
.pe-sec{font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink,#1c1b39);margin:18px 0 10px}
.pe-sec:first-child{margin-top:0}
.pe-photo-row{display:flex;align-items:center;gap:16px;margin-bottom:6px}
.pe-photo{position:relative;width:110px;height:110px;border-radius:50%;border:none;padding:0;cursor:pointer;
  background:#e9e9ee center/cover no-repeat;display:flex;align-items:center;justify-content:center;
  font-family:inherit;font-size:30px;font-weight:700;color:#8a8a92;overflow:visible}
.pe-photo img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.pe-photo-cam{position:absolute;right:2px;bottom:2px;width:34px;height:34px;border-radius:50%;
  background:#5b5f7b;color:#fff;display:flex;align-items:center;justify-content:center;border:3px solid #fff}
.pe-photo-hint{font-size:19px;font-weight:600;color:var(--ink,#1c1b39)}
.pe-f{display:block;margin-top:20px}
.pe-l{display:block;font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink,#1c1b39);margin-bottom:6px}
.pe-i{width:100%;box-sizing:border-box;border:none;border-bottom:1px solid #dcdae8;background:none;
  padding:8px 0;font-family:inherit;font-size:19px;color:var(--ink,#1c1b39)}
.pe-i:focus{outline:none;border-bottom-color:#8b8fa3}
/* el correo no se edita: es la identidad en Auth (ver member-profile) */
.pe-ro{padding:8px 0;font-size:19px;color:#5b5f7b;border-bottom:1px solid #eceaf3}
.pe-note{display:block;margin-top:5px;font-size:12.5px;color:#8b8fa3}
.pe-dob{display:flex;gap:14px}
.pe-dd{flex:0 0 70px}
.pe-yy{flex:0 0 96px}
.pe-ck{display:flex;align-items:flex-start;gap:12px;margin:16px 0;cursor:pointer}
.pe-ck input{position:absolute;opacity:0;width:0;height:0}
.pe-ck-box{flex:none;width:26px;height:26px;border-radius:5px;border:1.5px solid #cfcde0;margin-top:1px;
  display:flex;align-items:center;justify-content:center}
.pe-ck input:checked + .pe-ck-box{border-color:#2fb457}
.pe-ck input:checked + .pe-ck-box::after{content:'';width:13px;height:7px;border-left:2.5px solid #2fb457;
  border-bottom:2.5px solid #2fb457;transform:rotate(-45deg) translateY(-2px)}
.pe-ck-txt{font-size:15px;line-height:1.45;color:var(--ink,#1c1b39)}
.pe-err{margin:14px 0 4px;font-size:14px;line-height:1.45;color:#e5352b;min-height:1px}
.pe-foot{flex:none;padding:12px 20px calc(env(safe-area-inset-bottom,0px) + 16px);border-top:1px solid #eceaf3}
.pe-save{width:100%;padding:16px;border:none;border-radius:10px;cursor:pointer;font-family:inherit;
  font-size:18px;font-weight:600;color:var(--btn-gray-ink,#1c1b39);background:var(--btn-gray,#e4e4ea)}
.pe-save:disabled{opacity:.6;cursor:default}
/* el correo con el que estás registrado, bajo el nombre en el perfil */
.pf-email{margin:2px 0 0;text-align:center;font-size:14px;color:#8b8fa3;word-break:break-all}


/* ============ LOGIN / REGISTRO EN ESCRITORIO ============
   VA AL FINAL DEL ARCHIVO A PROPÓSITO. Estas reglas pisan las de `.lg*`, que viven ~900 líneas más
   abajo del resto de las de escritorio; con la misma especificidad gana la ÚLTIMA, así que puestas
   arriba no hacían nada (el botón de Face ID seguía saliendo y el título seguía pegado a la izquierda).

   El login se diseñó para un teléfono, o sea a todo el ancho. Suelto en un monitor daba campos de
   2000px y un "Log In" de lado a lado: se ve forzado y encima cuesta leer, porque el ojo tiene que
   recorrer toda la pantalla para volver al inicio del renglón siguiente. */
@media (min-width:900px){
  .lg{
    padding:40px 26px;justify-content:center;align-items:center;
    background:linear-gradient(180deg,#fafafb 0%,#fff 55%);
  }
  /* :not(.lg-close) — la X es absolute pero SIGUE siendo hija de .lg, así que el ancho de columna
     la agarraba y la estiraba en un óvalo de 400px. */
  .lg > *:not(.lg-close){width:100%;max-width:400px;margin-left:auto;margin-right:auto;flex:none}
  .lg-forgot{align-self:center;text-align:right}
  .lg-logo{margin:0 auto 8px;align-self:center}
  .lg-title, .lg-sub{text-align:center}
  /* Face ID es del teléfono: en una laptop ese botón no lleva a ningún lado */
  .lg-faceid, .lg-or{display:none !important}
  .lg-close{top:18px;right:18px}
}


/* ============ HORARIO EN ESCRITORIO — filas anchas (estilo Glofox) ============
   Al final del archivo por lo mismo que el login: estas reglas pisan a `.tt-*`, que viven cientos
   de líneas más abajo del bloque de escritorio, y con la misma especificidad gana la última. */
@media (min-width:900px){
  .tt-card{
    align-items:center;gap:24px;padding:22px 24px;
    border:1px solid var(--border);border-radius:14px;margin-bottom:12px;
    transition:border-color .15s,box-shadow .15s;
  }
  .tt-card:hover{border-color:#c9cad2;box-shadow:0 6px 18px -10px rgba(20,24,44,.28)}
  /* la miniatura al FRENTE: es lo que distingue una clase de otra de un vistazo, y en una fila
     ancha leerla al final obliga a cruzar toda la pantalla. */
  .tt-thumb{order:-1;width:104px;height:78px;border-radius:10px}
  .tt-name-txt{font-size:19px}
  .tt-sub{font-size:14px;margin-top:5px}
  /* la hora sale de encima de la foto y se vuelve su propia columna, alineada entre todas las
     filas: así el ojo baja por una sola línea de horas en vez de buscarla en cada tarjeta. */
  .tt-time{display:none}
  .tt-hour{
    display:block;order:-2;flex:none;width:82px;
    font-size:20px;font-weight:700;color:var(--ink);letter-spacing:.01em;
  }
  .tt-card.booked .tt-hour{color:#a0a0a6}
}


/* ============ LOGIN COMO POP-UP (portal web) ============
   Antes el login reemplazaba la app entera: la página se iba y el visitante quedaba sin referencia
   de dónde estaba. Ahora flota encima y el horario se sigue viendo atrás — cerrar es cerrar, no
   navegar a otro lado. */
.lg-modal{position:fixed;inset:0;z-index:400;display:flex;align-items:center;justify-content:center;padding:20px}
.lg-modal-bd{position:absolute;inset:0;background:rgba(12,12,14,.55);backdrop-filter:blur(3px)}
.lg-modal-card{
  position:relative;background:#fff;border-radius:22px;width:100%;max-width:440px;
  max-height:92vh;overflow-y:auto;box-shadow:0 30px 80px -18px rgba(0,0,0,.55);
}
/* dentro de la tarjeta el login deja de ser una pantalla completa y se vuelve contenido normal */
/* el login con foto (lg2) en la ventana de la web: la foto más baja y la tarjeta sin espacio de sobra */
.lg-modal-card .lg.lg2{padding:0;background:#f7f7f3}
.lg-modal-card .lg2-hero{height:150px;padding-top:0}
.lg-modal-card .lg2-logo{margin-bottom:18px}
.lg-modal-card .lg2-card{flex:none;margin-top:-20px;padding:26px 28px 24px}
.lg-modal-card .lg2-foot{margin-top:18px}
.lg-modal-card .device{height:auto;min-height:0;overflow:visible;background:none}
.lg-modal-card .lg{position:relative;inset:auto;height:auto;padding:44px 32px 32px;background:none;overflow:visible}
.lg-modal-card .lg > *{max-width:none}
.lg-modal-card .lg-faceid,.lg-modal-card .lg-or{display:none}
.lg-modal-card .lg-close{position:absolute;top:14px;right:14px;z-index:6}
@media (max-width:520px){
  /* en teléfono se pega abajo y ocupa casi todo el alto: un cuadrito centrado deja el teclado
     encima de los campos. */
  .lg-modal{align-items:flex-end;padding:0}
  .lg-modal-card{max-width:none;max-height:94vh;border-radius:22px 22px 0 0}
}


/* ============ FICHA DE CLASE DEL PORTAL (visitante) ============
   Clon del renglón de Glofox: bolita de estado + nombre + hora, píldora de disponibilidad, los
   datos debajo, y el botón Book a la derecha. La tarjeta NO es clicable — sólo el botón. */
.pt-legend{display:flex;gap:20px;justify-content:flex-end;padding:10px 18px 14px;font-size:13px;color:var(--muted)}
.pt-legend span{display:inline-flex;align-items:center;gap:7px}
.pt-dot{width:9px;height:9px;border-radius:50%;flex:none;display:inline-block}
.pt-dot.ok{background:#22c07d}
.pt-dot.full{background:#ef4a5a}
.pt-dot.wait{background:#f0913a}
.pt-dot.booked{background:#8b8b93}

.pt-card{
  position:relative;border:1px solid var(--border);border-radius:14px;
  padding:20px 22px;margin-bottom:14px;background:#fff;
}
.pt-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.pt-name{font-size:16px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink)}
.pt-when{font-size:15px;color:var(--muted)}
.pt-pill{
  display:inline-block;margin-top:12px;border-radius:20px;padding:5px 14px;
  font-size:13.5px;font-weight:600;background:rgba(34,192,125,.14);color:#12805c;
}
.pt-pill.full{background:rgba(239,74,90,.14);color:#c0392b}
.pt-pill.booked{background:rgba(139,139,147,.16);color:#5b5c67}
.pt-meta{margin-top:12px;font-size:14.5px;color:var(--muted);line-height:1.55}
.pt-meta b{color:var(--ink);font-weight:700}
.pt-book{
  position:absolute;right:22px;top:50%;transform:translateY(-50%);
  min-width:132px;height:50px;border-radius:25px;border:none;cursor:pointer;
  background:var(--book-bg,var(--ink,#111));color:var(--book-ink,#fff);font-family:inherit;font-size:16px;font-weight:600;
  transition:opacity .15s,transform .12s;
}
.pt-book:hover{opacity:.86}
.pt-book:active{transform:translateY(-50%) scale(.98)}
.pt-book[disabled]{background:#e6e6e9;color:#9a9aa2;cursor:not-allowed}
@media (max-width:640px){
  /* en teléfono el botón no cabe al lado: baja y ocupa el ancho */
  .pt-book{position:static;transform:none;width:100%;margin-top:16px}
  .pt-book:active{transform:scale(.99)}
}
/* Con varias presentaciones no hay precio hasta elegir talla. El bloque conserva su altura para
   que la descripción y el botón no brinquen cuando aparece. */
.pd-price{min-height:30px}
.pd-price-hint{font-size:15px;font-weight:500;color:var(--muted,#8b8fa3)}


/* ============ PORTAL: vistas List y Week ============
   Las elige el gym en CRM > Website Integration. La tira de fechas es de la vista por día; en las
   otras dos estorba, por eso se oculta desde aquí en vez de desmontarla (así volver a Day View no
   tiene que reconstruir el header). */
.hide-daystrip .tb-extra{display:none}

/* ---- encabezado común de List ---- */
.lv-top{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:20px 18px 6px}
.lv-cur{font-size:26px;font-weight:700;font-style:italic;color:var(--ink);letter-spacing:-.01em}
.lv-range{
  display:inline-flex;align-items:center;gap:8px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:15px;font-weight:600;color:var(--muted);padding:4px 6px;border-radius:8px;
}
.lv-range:hover{color:var(--ink);background:rgba(0,0,0,.05)}
.lv-range svg{width:18px;height:18px}
.lv-top .pt-legend{margin-left:auto;padding:0}
.lv-day{
  font-size:14px;font-weight:700;letter-spacing:.08em;color:var(--muted);
  padding:26px 4px 12px;
}

/* ---- rejilla semanal ---- */
.wk-top{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:18px 18px 10px}
.wk-nav{display:flex;align-items:center;gap:14px}
.wk-arrow{
  width:34px;height:34px;border-radius:50%;border:none;background:none;cursor:pointer;
  font-size:24px;line-height:1;color:var(--muted);display:flex;align-items:center;justify-content:center;
}
.wk-arrow:hover{background:rgba(0,0,0,.06);color:var(--ink)}
.wk-range{font-size:19px;font-weight:700;color:var(--ink);min-width:170px;text-align:center}
.wk-top .pt-legend{margin-left:auto;padding:0}

.wk{padding:0 4px 30px}
.wk-row{display:flex;align-items:stretch;gap:12px;margin-bottom:14px}
/* la etiqueta del día va VERTICAL, como en el portal de Glofox: ocupa 40px en vez de una fila
   completa, y con eso caben más clases a lo ancho sin que se pierda de qué día son. */
.wk-daylbl{
  flex:none;width:44px;border:1px solid var(--border);border-radius:10px;
  display:flex;align-items:center;justify-content:center;background:var(--surface,#fff);
}
.wk-daylbl span{
  writing-mode:vertical-rl;transform:rotate(180deg);
  font-size:13.5px;font-weight:600;color:var(--ink);letter-spacing:.02em;padding:14px 0;
}
.wk-cards{flex:1;min-width:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px}
.wk-card{
  position:relative;border:1px solid var(--border);border-radius:12px;padding:16px 18px 18px;
  background:var(--surface,#fff);transition:background .14s,border-color .14s,box-shadow .14s;
  min-height:132px;
}
.wk-card:hover{border-color:#c9cad2;box-shadow:0 8px 22px -12px rgba(20,24,44,.32)}
.wk-c-h{display:flex;align-items:center;gap:9px}
.wk-c-name{font-size:16px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink)}
.wk-c-when{margin-top:6px;font-size:14.5px;color:var(--muted)}
.wk-c-meta{margin-top:10px;font-size:13.5px;font-weight:600;color:var(--ink)}
/* el Book APARECE al pasar el mouse: un boton repetido en cada celda de la rejilla compite por la
   atencion y vuelve ilegible la semana completa, que es lo que se viene a leer. */
.wk-book{
  position:absolute;left:18px;bottom:14px;opacity:0;transform:translateY(4px);
  background:none;border:none;padding:0;cursor:pointer;font-family:inherit;
  font-size:15px;font-weight:600;color:var(--ink);text-decoration:underline;text-underline-offset:4px;
  transition:opacity .14s,transform .14s;
}
.wk-card:hover .wk-book{opacity:1;transform:none}
.wk-book[disabled]{color:var(--muted);text-decoration:none;cursor:not-allowed}
.wk-card.full{opacity:.62}
/* en pantalla tactil no hay hover: el boton se queda visible o no habria como reservar */
@media (hover:none){
  .wk-book{opacity:1;transform:none}
  .wk-card{min-height:150px}
}
@media (max-width:640px){
  .wk-daylbl{width:38px}
  .wk-cards{grid-template-columns:1fr}
  .lv-cur{font-size:22px}
}
/* el rango de la semana ahora es botón (abre el calendario): se le quita la ropa de botón */
.wk-range{background:none;border:none;font-family:inherit;cursor:pointer;padding:4px 8px;border-radius:8px}
.wk-range:hover{background:rgba(127,127,127,.12)}

/* ── FILTROS DEL PORTAL: Classes / Trainers (timetable.js → filtrosHtml) ─────────────────────
   Como el portal de Glofox: dos cajas lado a lado, etiqueta chica arriba y lo elegido abajo, el
   menú se despliega pegado debajo. Los grises son translúcidos para que sirvan igual sobre un
   portal negro que sobre uno blanco (los colores del gym los pone applyLook en --pt-*). */
.tf-bar{display:grid;grid-template-columns:1fr 1fr;margin:20px 18px 6px;border:1px solid var(--pt-line);position:relative;z-index:6}
.tf-box{position:relative;min-width:0}
.tf-box + .tf-box{border-left:1px solid var(--pt-line)}
.tf-head{width:100%;display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:14px;text-align:left;
  padding:13px 24px 14px;background:transparent;border:none;color:var(--pt-ink);font-family:inherit;cursor:pointer;
  transition:background .14s ease}
.tf-head:hover{background:rgba(127,127,127,.07)}
.tf-lbl{grid-column:1;font-size:11px;font-weight:400;letter-spacing:.07em;text-transform:uppercase;color:var(--pt-muted)}
.tf-val{grid-column:1;margin-top:3px;font-size:15px;font-weight:400;color:var(--pt-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tf-head svg{grid-column:2;grid-row:1 / span 2;width:18px;height:18px;color:var(--pt-ink);transition:transform .18s ease}
.tf-box.open .tf-head{background:rgba(127,127,127,.13)}
.tf-box.open .tf-head svg{transform:rotate(180deg)}
.tf-menu{display:none;position:absolute;left:-1px;right:-1px;top:100%;max-height:340px;overflow-y:auto;padding:8px 0;
  background:var(--pt-bg);border:1px solid var(--pt-line);box-shadow:0 16px 36px -10px rgba(0,0,0,.35);overscroll-behavior:contain}
.tf-box + .tf-box .tf-menu{left:0}
.tf-box.open .tf-menu{display:block}
.tf-opt{display:block;width:100%;text-align:left;padding:11px 24px;background:none;border:none;font-family:inherit;
  font-size:15px;font-weight:400;color:var(--pt-ink);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tf-opt:hover{background:rgba(127,127,127,.09)}
.tf-opt.on{background:rgba(127,127,127,.15)}
.tf-clear{margin-top:14px;background:none;border:1px solid var(--pt-line);border-radius:999px;padding:9px 18px;
  font-family:inherit;font-size:14px;color:var(--pt-ink);cursor:pointer}
.tf-clear:hover{background:rgba(127,127,127,.1)}
/* en escritorio todo va en la columna centrada de 1120px (.view > *): la barra se alinea con las
   tarjetas, no con el borde de la ventana — un margen propio le ganaba al centrado */
@media (min-width:900px){ .view > .tf-bar{margin:22px auto 8px} }
@media (max-width:640px){
  .tf-bar{margin:14px 12px 4px}
  .tf-head{padding:11px 14px 12px;column-gap:8px}
  .tf-val,.tf-opt{font-size:14px}
  .tf-opt{padding:11px 14px}
}

/* ── EL CALENDARIO DEL PORTAL (date-picker.js → CLIENT.openDatePop), el de Glofox ───────────
   Globo fijo a la ventana bajo el botón del rango: barra de días en negativo arriba (con su piquito)
   y los meses uno debajo de otro. Elegido = relleno; hoy = aro; fuera de rango = apagado. */
.dpp{position:fixed;z-index:460;width:340px;max-width:calc(100vw - 24px);background:var(--pt-bg);color:var(--pt-ink);
  border:1px solid var(--pt-line);box-shadow:0 22px 50px -12px rgba(0,0,0,.45);font-family:inherit;
  opacity:0;transform:translateY(-4px);transition:opacity .14s ease,transform .14s ease}
.dpp.on{opacity:1;transform:none}
.dpp-caret{position:absolute;top:-9px;width:0;height:0;border-left:10px solid transparent;border-right:10px solid transparent;
  border-bottom:10px solid var(--pt-ink)}
.dpp-wd{display:grid;grid-template-columns:repeat(7,1fr);padding:12px 12px;background:var(--pt-ink);color:var(--pt-bg);
  font-size:13px;font-weight:500;letter-spacing:.05em;text-align:center}
.dpp-months{overflow-y:auto;padding:0 12px 10px;overscroll-behavior:contain}
.dpp-month{display:grid;grid-template-columns:repeat(7,1fr);row-gap:6px;padding:12px 0 8px}
.dpp-month + .dpp-month{border-top:1px solid var(--pt-line)}
.dpp-mhead{display:flex;align-items:center;gap:4px;padding-left:10px;min-height:36px}
.dpp-mhead.full{grid-column:1 / -1;min-height:28px}
.dpp-mlabel{font-size:13.5px;font-weight:400;letter-spacing:.05em;color:var(--pt-ink);white-space:nowrap}
.dpp-next{display:inline-flex;align-items:center;background:none;border:none;padding:2px;color:var(--pt-ink);cursor:pointer;border-radius:6px}
.dpp-next:hover{background:rgba(127,127,127,.14)}
.dpp-day{justify-self:center;width:36px;height:36px;border-radius:50%;border:none;background:none;padding:0;
  display:flex;align-items:center;justify-content:center;font-family:inherit;font-size:13.5px;font-weight:700;
  color:var(--pt-ink);cursor:pointer;transition:background .12s ease}
.dpp-day:hover{background:rgba(127,127,127,.16)}
.dpp-day.today{box-shadow:inset 0 0 0 1px var(--pt-ink)}
.dpp-day.sel{background:var(--pt-ink);color:var(--pt-bg)}
.dpp-day.off{font-weight:400;color:var(--pt-muted);opacity:.55;cursor:default}
.dpp-day.off:hover{background:none}

/* ============ PERFIL DEL PORTAL WEB (modal de dos paneles) ============================
   Sólo lo monta profile-web.js, que sólo entra en navegador y de 900px para arriba. Debajo de eso
   el perfil del teléfono es el correcto y éste ni se crea. */
.pw-back{position:fixed;inset:0;z-index:120;background:rgba(0,0,0,.62);
  display:flex;align-items:center;justify-content:center;padding:28px}
.pw{display:grid;grid-template-columns:330px minmax(0,1fr);grid-template-rows:minmax(0,1fr);
  width:min(1180px,100%);height:min(760px,88vh);
  background:#141518;color:#fff;border:1px solid #2a2c31;border-radius:4px;overflow:hidden}
/* ⚠️ min-height:0 EN LOS DOS PANELES, y no es adorno: un hijo de grid trae min-height:auto, o sea
   que NO se encoge por debajo de su contenido. Con eso, el `overflow-y:auto` del panel izquierdo
   nunca se activaba —el panel crecía, .pw lo recortaba con su overflow:hidden— y el perfil
   quedaba cortado por abajo SIN barra para bajar. Es la misma trampa que ya tenía resuelta en
   .pw-panel con flex (flex:1;min-height:0) y que se me pasó aquí. */
.pw-left,.pw-right{min-height:0}

/* ── panel izquierdo: quién eres ───────────────────────────────────────────────────────── */
.pw-left{border-right:1px solid #2a2c31;padding:18px 24px 28px;overflow-y:auto;text-align:center}
.pw-logout{display:flex;align-items:center;gap:9px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:15px;color:#cfd2d6;padding:4px 0 18px}
.pw-logout svg{color:#cfd2d6}
.pw-logout:hover{color:#fff}
.pw-photo{width:190px;height:190px;border-radius:50%;margin:0 auto;background:#23252a center/cover no-repeat;
  display:flex;align-items:center;justify-content:center;color:#8a8d94;font-size:46px;font-weight:700}
.pw-credits{display:flex;align-items:center;justify-content:center;gap:14px;margin:26px 0 20px}
.pw-credits span{font-size:30px;font-weight:600}
.pw-pencil{background:none;border:none;cursor:pointer;color:#cfd2d6;display:flex;padding:4px}
.pw-pencil:hover{color:#fff}
.pw-fields{font-size:15px;line-height:1.9;color:#fff}
.pw-f span{color:#8a8d94}
/* el aviso informa, no alarma: azul apagado, no rojo */
.pw-note{display:flex;gap:10px;text-align:left;background:#152232;border:1px solid #1e3350;
  border-radius:4px;padding:11px 12px;margin:16px 0 6px;font-size:13px;line-height:1.45;color:#cfe0f5}
.pw-note svg{flex:none;color:#4ea0e8;margin-top:1px}
.pw-sect{text-align:left;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:#8a8d94;
  margin:26px 0 10px;padding-top:18px;border-top:1px solid #2a2c31}
.pw-docs{text-align:left}
.pw-doc{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;
  background:none;border:none;cursor:pointer;font-family:inherit;padding:9px 0;text-align:left}
.pw-doc-n{font-size:14px;color:#fff;text-decoration:underline;text-underline-offset:3px}
.pw-doc-s{flex:none;font-size:12px;font-weight:600}
.pw-doc-s.ok{color:#3bbf7a}
.pw-doc-s.pend{color:#e0a83c}
.pw-card{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-top:20px;padding-top:18px;border-top:1px solid #2a2c31}
.pw-card-t{display:flex;align-items:center;gap:9px;font-size:14px;color:#cfd2d6}
.pw-mini-btn{flex:none;border:none;border-radius:999px;background:#fff;color:#141518;cursor:pointer;
  font-family:inherit;font-size:14px;font-weight:600;padding:9px 20px}
.pw-pass{display:block;margin:22px auto 0;border:none;border-radius:999px;background:#fff;color:#141518;
  cursor:pointer;font-family:inherit;font-size:15px;font-weight:600;padding:12px 28px}

/* ── panel derecho: tu historial ───────────────────────────────────────────────────────── */
.pw-right{display:flex;flex-direction:column;min-width:0}
.pw-head{flex:none;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:22px 28px;border-bottom:1px solid #2a2c31}
.pw-head h2{margin:0;font-size:25px;font-weight:600}
.pw-x{background:none;border:none;cursor:pointer;color:#cfd2d6;display:flex;padding:4px}
.pw-x:hover{color:#fff}
.pw-tabs{flex:none;display:flex;gap:34px;padding:16px 28px 0}
.pw-tabs button{background:none;border:none;cursor:pointer;font-family:inherit;font-size:17px;
  color:#8a8d94;padding:0 0 10px;border-bottom:2px solid transparent}
.pw-tabs button.on{color:#fff;border-bottom-color:#fff}
.pw-panel{flex:1;min-height:0;overflow-y:auto;padding:22px 28px 28px}
.pw-sub{font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:#8a8d94;
  padding-bottom:12px;border-bottom:1px solid #2a2c31;margin-bottom:4px}
.pw-row{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding:16px 0;border-bottom:1px solid #22242a}
.pw-row-l{min-width:0}
.pw-row-t{font-size:19px;font-weight:600;color:#fff}
.pw-mini{font-size:13px;font-weight:400;color:#8a8d94;margin-left:9px}
.pw-row-s{font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:#8a8d94;margin-top:3px}
.pw-row-r{flex:none;text-align:right;font-size:14px;color:#cfd2d6}
.pw-amount{font-size:19px;font-weight:600;color:#fff}
.pw-dim{color:#8a8d94;font-size:15px;padding:10px 0}
.pw-dim2{color:#8a8d94;font-size:13px;margin-top:3px}
.pw-block{padding:16px 0;border-bottom:1px solid #22242a}
.pw-block-h{display:flex;align-items:center;justify-content:space-between;gap:14px}
.pw-block-t{font-size:21px;font-weight:600}
.pw-block-s{font-size:15px;color:#cfd2d6;margin-top:3px}
.pw-kv{font-size:14px;color:#8a8d94;margin-top:5px}
.pw-chip{flex:none;border-radius:999px;padding:4px 12px;font-size:12px;font-weight:600;
  background:rgba(255,255,255,.12);color:#fff}
.pw-chip.bad{background:#3a1114;color:#ff6b63}
.pw-chip.sm{display:inline-block;margin-top:8px;font-size:11px;padding:3px 10px}
.pw-cta{display:flex;align-items:center;justify-content:center;width:100%;margin-top:18px;border:none;
  border-radius:4px;background:#fff;color:#141518;cursor:pointer;font-family:inherit;
  font-size:16px;font-weight:600;padding:14px}
.pw-cta.ghost{background:none;border:1px solid #3a3d44;color:#fff;margin-top:10px}

/* Ventana baja: el modal deja de tener alto fijo y respira. */
@media (max-height:720px){ .pw{height:94vh} .pw-photo{width:130px;height:130px} }
/* Pantalla angosta o ventana a medias: el modal ocupa todo y los paneles se apilan, con el de
   datos arriba. Antes la rejilla de 330px + resto se estrujaba y el texto se partía letra a letra. */
@media (max-width:1040px){
  .pw-back{padding:0}
  .pw{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr);width:100%;height:100%;border:none;border-radius:0}
  .pw-left{border-right:none;border-bottom:1px solid #2a2c31;max-height:46vh}
}
