/* ============================================================================
   app.css — Componentes que la aplicacion necesita y que estilos.css no
   cubre. Se mantienen aparte para que estilos.css siga siendo el design
   system portable, sin mezclarlo con lo especifico de esta app.

   Mismos tokens (--bw-*) y mismo prefijo de clases.

   INDICE
   01. Accesibilidad (sr-only)
   02. Login
   03. Alertas / toasts
   04. Menu desplegable
   05. Estados vacios
   06. Paginacion
   07. Panel de filtros y chips
   08. Tablas: orden, acciones de fila
   09. Calendario: vista semana + slots pinchables
   10. Lista de asistentes de una clase
   11. Punto de venta (POS)
   12. Barras de progreso con etiqueta
   13. Formularios: errores de campo
   14. Impresion de ticket / factura
   ========================================================================== */


/* ============================================================================
   01. ACCESIBILIDAD
   ========================================================================== */
/* Texto solo para lectores de pantalla. Los iconos del sidebar son
   emojis; sin esto su nombre accesible seria el propio emoji. */
.bw-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* El layout original usaba 100vh, que en movil queda por debajo de la
   barra del navegador y recorta el contenido. */
@supports (height: 100dvh) {
  .bw-app { grid-template-rows: 100dvh; }
  .bw-main { height: 100dvh; }
}

/* Con las 10 secciones + logo, en pantallas bajas los ultimos iconos
   quedaban fuera de alcance. */
.bw-sidebar { overflow-y: auto; overscroll-behavior: contain; }
.bw-sidebar::-webkit-scrollbar { width: 0; }


/* ============================================================================
   02. LOGIN
   ========================================================================== */
.bw-login {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--bw-sp-4);
  background: linear-gradient(150deg, var(--bw-navy-2) 0%, var(--bw-navy) 60%, #06212F 100%);
}
.bw-login__card {
  width: 100%;
  max-width: 380px;
  background: var(--bw-white);
  border-radius: var(--bw-radius-lg);
  box-shadow: var(--bw-shadow-lg);
  padding: var(--bw-sp-7) var(--bw-sp-6) var(--bw-sp-6);
}
.bw-login__brand {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  margin-bottom: var(--bw-sp-6);
}
.bw-login__logo {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: var(--bw-radius-md);
  background: var(--bw-navy-2);
  color: var(--bw-white);
  font-weight: var(--bw-fw-bold);
  font-size: var(--bw-fs-xl);
  letter-spacing: .5px;
}
.bw-login__brand h1 { font-size: var(--bw-fs-2xl); margin: 0; color: var(--bw-navy-2); }
.bw-login__brand p  { font-size: var(--bw-fs-sm); margin: 2px 0 0; color: var(--bw-text-muted); }
.bw-login__footer {
  margin-top: var(--bw-sp-5);
  padding-top: var(--bw-sp-4);
  border-top: 1px solid var(--bw-border);
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
}


/* ============================================================================
   03. ALERTAS / TOASTS
   ========================================================================== */
.bw-alert {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border-radius: var(--bw-radius-md);
  border-left: 4px solid;
  margin-bottom: var(--bw-sp-4);
  font-size: var(--bw-fs-lg);
  line-height: var(--bw-lh-normal);
}
/* ---- Avisos en modal ----
   Van por encima de cualquier otro modal: casi todo el panel se opera
   dentro de uno, y un aviso por debajo del velo no se lee. */
.bw-aviso-modal { z-index: var(--bw-z-aviso); }
.bw-aviso-modal__caja {
  max-width: 460px;
  border-top: 4px solid var(--bw-success);
  padding: var(--bw-sp-5);
}
.bw-aviso-modal--danger  .bw-aviso-modal__caja,
.bw-aviso-modal__caja.bw-aviso-modal--danger  { border-top-color: var(--bw-danger); }
.bw-aviso-modal--warning .bw-aviso-modal__caja,
.bw-aviso-modal__caja.bw-aviso-modal--warning { border-top-color: var(--bw-warning); }

.bw-aviso-modal__cuerpo { display: flex; gap: var(--bw-sp-4); align-items: flex-start; }
.bw-aviso-modal__icono { font-size: 24px; line-height: 1.2; flex: 0 0 auto; }
.bw-aviso-modal__titulo {
  margin: 0 0 var(--bw-sp-2);
  font-size: var(--bw-fs-xl);
  color: var(--bw-navy-2);
}
/* Varios avisos en el mismo modal: cada uno su parrafo, sin viuda al
   final. */
.bw-aviso-modal__texto { margin: 0 0 var(--bw-sp-2); line-height: var(--bw-lh-normal); }
.bw-aviso-modal__texto:last-child { margin-bottom: 0; }
.bw-aviso-modal__pie { display: flex; justify-content: flex-end; margin-top: var(--bw-sp-5); }

.bw-alert--success { background: #EAF6ED; border-color: var(--bw-success); color: #1E5C32; }
.bw-alert--danger  { background: var(--bw-red-soft);    border-color: var(--bw-danger);  color: #8C3315; }
.bw-alert--warning { background: var(--bw-yellow-soft); border-color: var(--bw-warning); color: #6B4C07; }
.bw-alert--info    { background: var(--bw-teal-soft);   border-color: var(--bw-teal-text); color: #014A52; }
.bw-alert__close {
  background: none; border: 0; cursor: pointer;
  font-size: var(--bw-fs-xl); line-height: 1;
  color: inherit; opacity: .6; padding: 0 2px;
}
.bw-alert__close:hover { opacity: 1; }


/* ----------------------------------------------------------------------------
   Modales: .bw-overlay lleva display:flex en estilos.css, que gana al
   atributo [hidden] (que solo aplica display:none con especificidad 0).
   Sin esto, TODOS los modales de la pagina aparecen abiertos al cargar.
   -------------------------------------------------------------------------- */
.bw-overlay[hidden] { display: none !important; }


/* ============================================================================
   04. MENU DESPLEGABLE
   ========================================================================== */
.bw-menu { position: relative; }
.bw-menu__panel {
  position: absolute;
  right: 0; top: calc(100% + 8px);
  min-width: 200px;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-md);
  box-shadow: var(--bw-shadow-md);
  z-index: var(--bw-z-popover);
  overflow: hidden;
}
.bw-menu__panel[hidden] { display: none; }
.bw-menu__header {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border-bottom: 1px solid var(--bw-border);
  margin: 0;
  font-size: var(--bw-fs-md);
}
.bw-menu__item {
  display: block; width: 100%;
  padding: var(--bw-sp-3) var(--bw-sp-4);
  background: none; border: 0;
  text-align: left; cursor: pointer;
  font: inherit; color: var(--bw-text);
}
.bw-menu__item:hover { background: var(--bw-bg-200); }


/* ============================================================================
   05. ESTADOS VACIOS
   ========================================================================== */
.bw-empty {
  text-align: center;
  padding: var(--bw-sp-9) var(--bw-sp-5);
  color: var(--bw-text-muted);
}
.bw-empty__icon { font-size: 40px; display: block; margin-bottom: var(--bw-sp-3); opacity: .5; }
.bw-empty__title { font-size: var(--bw-fs-xl); color: var(--bw-text); margin: 0 0 var(--bw-sp-2); }
.bw-empty p { margin: 0 0 var(--bw-sp-4); }


/* ============================================================================
   06. PAGINACION
   ========================================================================== */
.bw-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-4);
  margin-top: var(--bw-sp-4);
  flex-wrap: wrap;
}
.bw-pagination__info { font-size: var(--bw-fs-md); color: var(--bw-text-muted); }
.bw-pagination__pages { display: flex; gap: 4px; }
.bw-pagination__page {
  min-width: 30px; height: 30px;
  display: grid; place-items: center;
  padding: 0 var(--bw-sp-2);
  border: 1px solid var(--bw-border-strong);
  border-radius: var(--bw-radius-sm);
  background: var(--bw-white);
  color: var(--bw-text);
  text-decoration: none;
  font-size: var(--bw-fs-md);
}
.bw-pagination__page:hover { background: var(--bw-bg-200); }
.bw-pagination__page.is-active {
  background: var(--bw-teal-text);
  border-color: var(--bw-teal-text);
  color: var(--bw-white);
  font-weight: var(--bw-fw-semibold);
}
.bw-pagination__page.is-disabled { opacity: .45; pointer-events: none; }


/* ============================================================================
   07. PANEL DE FILTROS Y CHIPS
   ========================================================================== */
.bw-layout-filtros {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--bw-sp-5);
  align-items: start;
}
.bw-filtros {
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  padding: var(--bw-sp-4);
}
.bw-filtros__group { margin-bottom: var(--bw-sp-4); }
.bw-filtros__group:last-child { margin-bottom: 0; }
.bw-filtros__label {
  display: block;
  font-size: var(--bw-fs-sm);
  font-weight: var(--bw-fw-semibold);
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--bw-text-muted);
  margin-bottom: var(--bw-sp-2);
}
.bw-chips { display: flex; flex-wrap: wrap; gap: var(--bw-sp-2); margin-bottom: var(--bw-sp-3); }
.bw-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px var(--bw-sp-3);
  border-radius: var(--bw-radius-full);
  background: var(--bw-teal-soft);
  color: #014A52;
  font-size: var(--bw-fs-sm);
  font-weight: var(--bw-fw-medium);
}
.bw-chip a { color: inherit; text-decoration: none; opacity: .7; font-size: var(--bw-fs-lg); line-height: 1; }
.bw-chip a:hover { opacity: 1; }

@media (max-width: 900px) {
  .bw-layout-filtros { grid-template-columns: 1fr; }
}


/* ============================================================================
   08. TABLAS: ORDEN Y ACCIONES DE FILA
   ========================================================================== */
.bw-table th a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.bw-table th a:hover { color: var(--bw-teal-text); }
.bw-table__sort { opacity: .35; font-size: 9px; }
.bw-table th a.is-sorted .bw-table__sort { opacity: 1; color: var(--bw-teal-text); }
/* La celda de acciones se define mas abajo, en su propio bloque. Aqui
   habia un display:flex duplicado que seguia ganando por orden y sacaba
   la celda del modelo de columnas. */

/* En tablas densas el translateY(-1px) del hover global de .bw-btn
   produce parpadeo al desplazar el raton por las filas. */
.bw-table .bw-btn:hover { transform: none; }


/* ============================================================================
   09. CALENDARIO: VISTA SEMANA Y SLOTS
   ========================================================================== */
/* estilos.css solo define la vista Dia (.bw-cal-grid es "56px 1fr").
   La vista Semana necesita 7 columnas. */
.bw-cal-grid--semana { grid-template-columns: 56px repeat(7, minmax(0, 1fr)); }

.bw-cal-head {
  display: grid;
  grid-template-columns: 56px repeat(7, minmax(0, 1fr));
  position: sticky; top: 0;
  background: var(--bw-white);
  z-index: 2;
  border-bottom: 1px solid var(--bw-border);
}
.bw-cal-head__day {
  padding: var(--bw-sp-2);
  text-align: center;
  font-size: var(--bw-fs-sm);
  font-weight: var(--bw-fw-semibold);
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--bw-text-muted);
  border-left: 1px solid var(--bw-border);
}
.bw-cal-head__day.is-today { color: var(--bw-teal-text); background: var(--bw-teal-soft); }
.bw-cal-head__day span { display: block; font-size: var(--bw-fs-xl); color: var(--bw-text); text-transform: none; }
.bw-cal-head__day.is-today span { color: var(--bw-teal-text); }

/* Hueco libre pinchable: es el "arrastra para fijar la hora" del panel
   real, reducido a un clic (crear cita en ese hueco). */
.bw-cal-slot--libre { cursor: pointer; transition: background var(--bw-transition); }
.bw-cal-slot--libre:hover { background: var(--bw-teal-soft); }
.bw-cal-slot--libre:hover::after {
  content: '+';
  display: grid; place-items: center;
  height: 100%;
  color: var(--bw-teal-text);
  font-size: var(--bw-fs-xl);
  font-weight: var(--bw-fw-bold);
}
.bw-cal-slot--cerrado { background: repeating-linear-gradient(45deg, var(--bw-bg-200) 0 6px, var(--bw-bg-300) 6px 12px); }

.bw-event { text-decoration: none; color: inherit; display: block; }
.bw-event--llena { border-left-color: var(--bw-danger); }
.bw-event--cancelada { opacity: .5; text-decoration: line-through; }


/* ============================================================================
   10. LISTA DE ASISTENTES DE UNA CLASE
   ========================================================================== */
/* Es la pantalla operativa central: el profesor pasa lista aqui. */
.bw-asistentes { list-style: none; margin: 0; padding: 0; }
.bw-asistente {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-2) 0;
  border-bottom: 1px solid var(--bw-border);
}
.bw-asistente:last-child { border-bottom: 0; }
.bw-asistente__num {
  width: 20px;
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.bw-asistente__nombre { flex: 1; min-width: 0; }
.bw-asistente__nombre a { color: var(--bw-text); text-decoration: none; font-weight: var(--bw-fw-medium); }
.bw-asistente__nombre a:hover { color: var(--bw-teal-text); }
.bw-asistente__fuente { display: block; font-size: var(--bw-fs-sm); color: var(--bw-text-muted); }
.bw-asistente--espera { opacity: .75; }
.bw-asistente--espera .bw-asistente__num::before { content: 'E'; }

.bw-aforo {
  display: inline-flex; align-items: baseline; gap: 2px;
  font-variant-numeric: tabular-nums;
  font-weight: var(--bw-fw-semibold);
}
.bw-aforo--lleno { color: var(--bw-danger); }

/* Contador de la lista de espera, al lado del aforo. En gris y con el
   reloj de arena porque no son plazas: son gente esperando a que se
   libere una, y confundir las dos cifras es justo lo que hay que evitar. */
.bw-aforo--espera {
  margin-left: var(--bw-sp-2);
  color: var(--bw-text-muted);
  font-weight: var(--bw-fw-medium);
}
.bw-aforo--espera i { font-size: .85em; margin-right: 2px; }
.bw-aforo--espera.bw-aforo--lleno { color: var(--bw-warning, var(--bw-danger)); }


/* ============================================================================
   11. PUNTO DE VENTA
   ========================================================================== */
.bw-pos { display: grid; grid-template-columns: 1fr 340px; gap: var(--bw-sp-5); align-items: start; }
.bw-pos__lineas { width: 100%; }
/* El TPV en modal necesita mas ancho que una ficha: son dos columnas
   —lineas de venta y totales— y a 920px el nombre del articulo se queda
   en "Elige u". Se le da su propio ancho en vez de apretar la tabla,
   porque lo que hay que leer es justo ese nombre. */
/* ---- Vistas guardadas ----
   Una fila de atajos bajo las pestanas de periodo. Envuelven: quien
   guarda diez busquedas no puede quedarse sin ver las ultimas. */
.bw-vistas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bw-sp-2);
  margin-top: var(--bw-sp-3);
}
.bw-vista {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-full);
  background: var(--bw-white);
  font-size: var(--bw-fs-md);
}
.bw-vista a { color: var(--bw-text); text-decoration: none; }
.bw-vista.is-activa { border-color: var(--bw-principal-text); background: var(--bw-bg-200); }
.bw-vista.is-activa a { font-weight: var(--bw-fw-semibold); }
.bw-vista__marca { color: var(--bw-warning); font-size: var(--bw-fs-sm); }
/* El aspa forma parte de la pastilla, no es un boton aparte. */
.bw-vista form { display: contents; }
.bw-vista__quitar {
  background: none; border: 0; padding: 0 0 0 2px;
  color: var(--bw-text-muted); cursor: pointer; font-size: var(--bw-fs-lg); line-height: 1;
}
.bw-vista__quitar:hover { color: var(--bw-danger); }

/* Fila de deuda o cuota en el TPV: descripcion elastica, importe y boton
   pegados a la derecha. */
.bw-deuda {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-3) 0;
  border-bottom: 1px solid var(--bw-border);
}
.bw-deuda:last-child { border-bottom: 0; }
.bw-deuda__que { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.bw-deuda__que .bw-text-muted { font-size: var(--bw-fs-sm); }

/* Lo que se debe lleva marco: entre tarjetas iguales, la unica que pide
   una decision tiene que distinguirse de las demas. */
.bw-card--aviso { border-color: var(--bw-danger); }

/* El salto a fecha de la agenda. Se ajusta al ancho de la fecha en vez
   de estirarse: al lado de tres botones pequeños, un campo a ancho
   completo se lee como si fuera el protagonista de la barra. */
.bw-calendar__salto { display: flex; gap: var(--bw-sp-2); align-items: center; }
.bw-calendar__salto .bw-input {
  width: auto;
  padding: 5px 8px;
  font-size: var(--bw-fs-md);
}

.bw-modal-remoto--amplio .bw-modal--ancho {
  width: min(1200px, 96vw);
  max-width: min(1200px, 96vw);
}
.bw-pos__total {
  display: flex; justify-content: space-between;
  padding: var(--bw-sp-2) 0;
  font-size: var(--bw-fs-lg);
}
.bw-pos__total--final {
  border-top: 2px solid var(--bw-navy-2);
  margin-top: var(--bw-sp-2);
  padding-top: var(--bw-sp-3);
  font-size: var(--bw-fs-2xl);
  font-weight: var(--bw-fw-bold);
  color: var(--bw-navy-2);
}
@media (max-width: 1000px) { .bw-pos { grid-template-columns: 1fr; } }


/* ============================================================================
   12. PROGRESO CON ETIQUETA
   ========================================================================== */
.bw-progress-wrap { display: flex; align-items: center; gap: var(--bw-sp-3); }
.bw-progress-wrap .bw-progress { flex: 1; }
.bw-progress__label {
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}


/* ============================================================================
   13. FORMULARIOS: ERRORES DE CAMPO
   ========================================================================== */
.bw-input.is-invalid,
.bw-select.is-invalid,
.bw-textarea.is-invalid { border-color: var(--bw-danger); }
.bw-field-error {
  display: block;
  margin-top: 4px;
  font-size: var(--bw-fs-sm);
  color: var(--bw-danger);
}
.bw-required { color: var(--bw-danger); }


/* ============================================================================
   15. PORTAL PUBLICO DE RESERVA
   El panel es una app de escritorio a pantalla completa; el portal lo
   usa un cliente desde el movil, casi siempre de pie en la calle. De
   ahi que no comparta layout: ancho contenido, texto mas grande que el
   12px del panel, y botones con area de toque suficiente.
   ========================================================================== */
.bw-portal {
  background: var(--bw-bg-100);
  color: var(--bw-text);
  font-size: var(--bw-fs-lg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.bw-portal__header {
  background: var(--bw-white);
  border-bottom: 1px solid var(--bw-border);
  position: sticky;
  top: 0;
  z-index: var(--bw-z-topbar);
}
.bw-portal__bar {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--bw-sp-3) var(--bw-sp-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-4);
  flex-wrap: wrap;
}
.bw-portal__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--bw-sp-2);
  font-weight: var(--bw-fw-bold);
  font-size: var(--bw-fs-xl);
  color: var(--bw-navy-2);
  text-decoration: none;
}
.bw-portal__logo-mark {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--bw-radius-md);
  background: var(--bw-navy-2);
  color: var(--bw-white);
  font-size: var(--bw-fs-md);
}
.bw-portal__nav {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-4);
  flex-wrap: wrap;
}
.bw-portal__nav > a:not(.bw-btn) {
  color: var(--bw-text-muted);
  text-decoration: none;
  font-weight: var(--bw-fw-medium);
  padding: var(--bw-sp-1) 0;
  border-bottom: 2px solid transparent;
}
.bw-portal__nav > a:not(.bw-btn):hover { color: var(--bw-text); }
.bw-portal__nav > a.is-active {
  color: var(--bw-teal-text);
  border-bottom-color: var(--bw-teal-text);
}
.bw-portal__salir { margin: 0; }

.bw-portal__main {
  flex: 1;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: var(--bw-sp-6) var(--bw-sp-4) var(--bw-sp-9);
}

.bw-portal__footer {
  background: var(--bw-white);
  border-top: 1px solid var(--bw-border);
  padding: var(--bw-sp-5) var(--bw-sp-4);
  text-align: center;
  color: var(--bw-text-muted);
  font-size: var(--bw-fs-md);
}
.bw-portal__footer p { margin: 0; }

/* Lista de barras comparativas: nombre, barra y cifra en una linea.
   Las tres columnas son fijas a los lados y elastica en medio, para que
   las barras arranquen y acaben alineadas aunque los nombres midan
   distinto: si no, comparar de un vistazo deja de funcionar. */
.bw-barras { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--bw-sp-3); }
.bw-barra {
  display: grid;
  /* La cifra en `auto` y no en ancho fijo: las hay de 3 caracteres ("7")
     y de diez ("1.234,00 €"), y con ancho fijo las segundas se salen. */
  grid-template-columns: minmax(90px, 150px) 1fr auto;
  align-items: center;
  gap: var(--bw-sp-3);
  font-size: var(--bw-fs-md);
}
.bw-barra__nombre {
  color: var(--bw-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bw-barra__pista {
  height: 10px;
  border-radius: var(--bw-radius-full);
  background: var(--bw-bg-300);
  overflow: hidden;
}
.bw-barra__relleno {
  display: block;
  height: 100%;
  background: var(--bw-teal-2);
  border-radius: var(--bw-radius-full);
}
.bw-barra__cifra {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--bw-text-muted);
}
/* Para importes, que no caben en los 44px de un contador. */
.bw-barra__cifra--ancha { white-space: nowrap; }

/* El reparto en crudo bajo una barra de ocupacion: un 100% de dos plazas
   y uno de veinte no son la misma noticia. */
.bw-barra__pie {
  list-style: none;
  margin: -6px 0 2px;
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
}

/* Por debajo del 40% la barra cambia de color: en una lista larga de
   ocupaciones, el hueco es justo lo que se viene a buscar. */
.bw-barra__relleno--flojo { background: var(--bw-orange); }

.bw-portal__consentimiento { margin-top: var(--bw-sp-2); }

/* Es un boton porque cambia algo en el servidor, pero se lee como un
   enlace: en un pie, un boton con marco pediria mas atencion de la que
   merece. */
.bw-enlace-sobrio {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
  text-decoration: underline;
  cursor: pointer;
}
.bw-enlace-sobrio:hover { color: var(--bw-text); }

/* Solo la primera letra. text-transform:capitalize pondria mayuscula en
   cada palabra y "viernes 7 de agosto" saldria "Viernes 7 De Agosto". */
.bw-capitalizar::first-letter { text-transform: uppercase; }

.bw-portal__hero { margin-bottom: var(--bw-sp-6); }
.bw-portal__hero h1 {
  font-size: var(--bw-fs-3xl);
  color: var(--bw-navy-2);
  margin: 0 0 var(--bw-sp-2);
}
.bw-portal__hero p { margin: 0 0 var(--bw-sp-2); }
.bw-portal__hero--compacto h1 { font-size: var(--bw-fs-2xl); }

/* Catalogo */
.bw-portal__servicios {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--bw-sp-4);
}
.bw-portal__servicio {
  display: block;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  padding: var(--bw-sp-5);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--bw-transition), box-shadow var(--bw-transition);
}
.bw-portal__servicio:hover {
  border-color: var(--bw-teal-text);
  box-shadow: var(--bw-shadow-card);
}
.bw-portal__servicio h3 {
  margin: 0 0 var(--bw-sp-2);
  font-size: var(--bw-fs-xl);
  color: var(--bw-navy-2);
}
.bw-portal__servicio p { margin: 0 0 var(--bw-sp-3); }
.bw-portal__servicio-meta {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  flex-wrap: wrap;
}
.bw-portal__servicio-cta {
  color: var(--bw-teal-text);
  font-weight: var(--bw-fw-semibold);
}

/* Huecos y clases */
.bw-portal__selector-dia {
  /* Dia y "con quien" uno al lado del otro: son dos filtros de lo mismo
     y apilados ocupaban media pantalla antes de ver un solo hueco. Sin
     max-width fijo, porque ahora el ancho depende de si hay uno o dos. */
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-4);
  align-items: end;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  padding: var(--bw-sp-4);
  margin-bottom: var(--bw-sp-4);
}

.bw-portal__selector-dia > div { flex: 1 1 200px; min-width: 0; }
.bw-portal__selector-dia .bw-input,
.bw-portal__selector-dia .bw-select { width: 100%; }

@media (max-width: 560px) {
  /* En movil uno debajo de otro: dos campos de 150px no dejan leer un
     nombre y apellido. */
  .bw-portal__selector-dia > div { flex-basis: 100%; }
}
.bw-portal__huecos { display: flex; flex-direction: column; gap: var(--bw-sp-2); }
.bw-portal__hueco-form { margin: 0; }
.bw-portal__hueco {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  flex-wrap: wrap;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-left: 4px solid var(--bw-teal-2);
  border-radius: var(--bw-radius-md);
  padding: var(--bw-sp-3) var(--bw-sp-4);
}
.bw-portal__hueco.is-completa { border-left-color: var(--bw-danger); }
.bw-portal__hueco-hora {
  font-size: var(--bw-fs-xl);
  font-weight: var(--bw-fw-bold);
  color: var(--bw-navy-2);
  font-variant-numeric: tabular-nums;
  min-width: 58px;
}
.bw-portal__hueco-info {
  flex: 1;
  min-width: 140px;
  display: flex;
  align-items: center;
  gap: var(--bw-sp-2);
  flex-wrap: wrap;
  color: var(--bw-text-muted);
}
.bw-portal__hueco .bw-select { max-width: 230px; }

/* Mis reservas */
.bw-portal__reservas { display: flex; flex-direction: column; gap: var(--bw-sp-3); }
.bw-portal__reserva {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-4);
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  padding: var(--bw-sp-4);
  flex-wrap: wrap;
}
.bw-portal__reserva-fecha {
  display: grid;
  place-items: center;
  min-width: 58px;
  padding: var(--bw-sp-2);
  border-radius: var(--bw-radius-md);
  background: var(--bw-teal-soft);
  color: #014A52;
}
.bw-portal__reserva-dia {
  font-size: var(--bw-fs-2xl);
  font-weight: var(--bw-fw-bold);
  line-height: 1;
}
.bw-portal__reserva-mes { font-size: var(--bw-fs-sm); text-transform: uppercase; }
.bw-portal__reserva-datos { flex: 1; min-width: 190px; }
.bw-portal__reserva-datos h3 { margin: 0 0 2px; font-size: var(--bw-fs-xl); }
.bw-portal__reserva-datos p { margin: 0 0 var(--bw-sp-1); }
.bw-portal__reserva-accion { text-align: right; }

/* Formularios centrados (acceder, registro, recuperar) */
.bw-portal__form {
  max-width: 460px;
  margin: 0 auto;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  padding: var(--bw-sp-6);
}

@media (max-width: 640px) {
  .bw-portal__bar { padding: var(--bw-sp-3); }
  .bw-portal__main { padding: var(--bw-sp-4) var(--bw-sp-3) var(--bw-sp-8); }
  .bw-portal__hueco { align-items: stretch; flex-direction: column; }
  .bw-portal__hueco .bw-select,
  .bw-portal__hueco .bw-btn { max-width: none; width: 100%; }
  .bw-portal__reserva-accion { width: 100%; text-align: left; }
}



/* ---- Tienda del alumno ----
   Reutiliza el lenguaje del catalogo de servicios (misma rejilla, misma
   tarjeta) en lugar de inventar uno nuevo: para el alumno, comprar un
   bono y elegir una clase son la misma clase de decision, y verlas
   distintas solo anadiria ruido. */
.bw-portal__section { margin-bottom: var(--bw-sp-6); }

.bw-portal__subtitle {
  margin: 0 0 var(--bw-sp-4);
  font-size: var(--bw-fs-xl);
  color: var(--bw-navy-2);
}

.bw-portal__lead {
  margin: 0 0 var(--bw-sp-4);
  color: var(--bw-text-muted);
}

.bw-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--bw-sp-4);
  align-items: start;
}

.bw-card--producto {
  display: flex;
  flex-direction: column;
}

/* El boton se pega abajo aunque las descripciones tengan distinto largo:
   una fila de botones a alturas distintas se lee como desorden. */
.bw-card--producto .bw-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--bw-sp-2);
  height: 100%;
}
.bw-card--producto .bw-precio { margin-top: auto; padding-top: var(--bw-sp-2); }
.bw-card--producto form { margin-top: var(--bw-sp-2); }
.bw-card--producto .bw-btn { width: 100%; }

.bw-precio {
  margin: var(--bw-sp-2) 0 0;
  font-size: var(--bw-fs-2xl);
  font-weight: 600;
  color: var(--bw-navy-2);
}
.bw-precio__periodo {
  font-size: var(--bw-fs-sm);
  font-weight: 400;
  color: var(--bw-text-muted);
}

/* Toda la fila es pulsable, no solo el circulito: en un movil acertar en
   16px de radio es justo lo que hace que la gente falle. */
.bw-radio {
  display: flex;
  align-items: baseline;
  gap: var(--bw-sp-2);
  flex-wrap: wrap;
  padding: var(--bw-sp-3);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-lg);
  margin-bottom: var(--bw-sp-2);
  cursor: pointer;
}
.bw-radio:hover { border-color: var(--bw-teal-text); }
.bw-radio .bw-help { flex-basis: 100%; margin: 0; }

.bw-form-inline {
  display: flex;
  align-items: flex-end;
  gap: var(--bw-sp-2);
  flex-wrap: wrap;
}

/* El desglose de la compra tiene dos columnas y tiene que caber en un
   movil: aqui NO vale el scroll lateral de las tablas del panel, porque
   la cifra que se esconderia a la derecha es justo el importe.

   El concepto puede ser largo —una suscripcion prorrateada arrastra su
   explicacion— asi que se le deja partir por donde haga falta y se fija
   el importe a su ancho minimo. */
/* El min-width:560px que estilos.css pone a TODA .bw-table en movil es
   para las tablas densas del panel, que viven dentro de un
   .bw-table-wrap con scroll propio. Esta no: esta suelta en una tarjeta,
   asi que ese minimo empuja la PAGINA entera y saca el importe fuera de
   la pantalla. De ahi el !important, que aqui es la forma honesta de
   decir "esta tabla juega con otras reglas". */
.bw-tabla-compra { width: 100%; min-width: 0 !important; table-layout: fixed; }
.bw-tabla-compra td,
.bw-tabla-compra th { overflow-wrap: anywhere; }
.bw-tabla-compra .bw-table__num { width: 7.5em; white-space: nowrap; }

@media (max-width: 640px) {
  /* Una columna: dos tarjetas de 130px no dejan leer ni el nombre. */
  .bw-card-grid { grid-template-columns: 1fr; }

  /* El cupon a ancho completo, con el boton debajo. */
  .bw-form-inline > .bw-input,
  .bw-form-inline > .bw-btn { width: 100%; max-width: none; }

  /* Facturas: la tabla pasa a una tarjeta por factura.
     Con seis columnas en 390px el scroll lateral dejaba fuera el importe,
     el estado y el boton de pagar --justo a lo que se entra--, y nada
     indicaba que hubiera mas a la derecha. Apilada se ve entera.
     La cabecera se oculta porque cada celda lleva ya su etiqueta en
     data-th; se usa clip y no display:none para que los lectores de
     pantalla sigan anunciando la tabla. */
  /* estilos.css le pone min-width:560px a TODA .bw-table en movil para
     que las del panel hagan scroll dentro de su caja. Apilada esa
     anchura no tiene sentido y empuja los botones a 504px en una
     pantalla de 390. Mismo caso --y misma solucion-- que
     .bw-tabla-compra. */
  .bw-tabla-facturas { min-width: 0 !important; }

  .bw-tabla-facturas thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .bw-tabla-facturas,
  .bw-tabla-facturas tbody,
  .bw-tabla-facturas tr,
  .bw-tabla-facturas td { display: block; width: auto; }

  .bw-tabla-facturas tr {
    padding: var(--bw-sp-3);
    border-bottom: 1px solid var(--bw-border);
  }

  .bw-tabla-facturas tr:last-child { border-bottom: 0; }

  .bw-tabla-facturas td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--bw-sp-3);
    border: 0;
    padding: 2px 0;
    text-align: left;
  }

  /* La etiqueta de la columna, delante del dato. */
  .bw-tabla-facturas td[data-th]::before {
    content: attr(data-th);
    flex: 0 0 auto;
    color: var(--bw-text-muted, #666);
    font-size: var(--bw-fs-sm, .85rem);
  }

  /* Los botones, a lo ancho y debajo: en el movil se pulsan con el dedo. */
  .bw-tabla-facturas .bw-factura__acciones {
    justify-content: stretch;
    padding-top: var(--bw-sp-3);
  }

  .bw-tabla-facturas .bw-factura__acciones::before { content: none; }
  .bw-tabla-facturas .bw-factura__acciones form { flex: 1 1 auto; }
  .bw-tabla-facturas .bw-factura__acciones .bw-btn { width: 100%; }
}

/* ============================================================================
   14. IMPRESION
   ========================================================================== */
@media print {
  .bw-sidebar, .bw-subnav, .bw-topbar, .bw-alert, .bw-btn, .bw-pagination { display: none !important; }
  .bw-app { display: block; }
  .bw-main, .bw-content { height: auto; overflow: visible; padding: 0; }
  .bw-card { box-shadow: none; border: 0; }
  body { background: #fff; font-size: 11pt; }
  a[href]::after { content: ''; }
}

/* Ticket de 80 mm (ticket_print_configs.paper_width) */
.bw-ticket {
  width: 80mm;
  margin: 0 auto;
  font-family: 'Courier New', monospace;
  font-size: 11px;
  line-height: 1.4;
}
.bw-ticket hr { border: 0; border-top: 1px dashed #000; margin: 6px 0; }
.bw-ticket__row { display: flex; justify-content: space-between; gap: 8px; }
@media print { @page { margin: 4mm; } }


/* ============================================================================
   15. AGENDA: SERIES, INSTRUCTORES Y ETIQUETAS
   ========================================================================== */
.bw-separador { border: 0; border-top: 1px solid var(--bw-border); margin: var(--bw-sp-4) 0; }

/* Rejilla de casillas (dias de la semana, instructores). auto-fill en vez
   de flex para que las siete casillas queden alineadas en columnas y no
   escalonadas segun el largo del nombre. */
.bw-check-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: var(--bw-sp-2);
}
.bw-check-row .bw-check { margin: 0; }

/* Para listas de nombres completos: con 88px "Carla Vandervaart" se parte
   en dos lineas y la casilla queda descolgada arriba. */
.bw-check-row--ancho { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }

.bw-chip--serie { background: var(--bw-purple-soft, #EDE7F6); color: #3B2A6B; }

/* ============================================================================
   16. CONFIGURACION: COLOR DE MARCA Y MUESTRA DE CONTRASTE
   ========================================================================== */
.bw-color-campo { display: flex; align-items: center; gap: var(--bw-sp-2); }
.bw-color-campo input[type="color"] {
  width: 46px; height: 30px; padding: 2px;
  border: 1px solid var(--bw-border-input);
  border-radius: var(--bw-radius-sm);
  background: var(--bw-white);
  cursor: pointer;
}
.bw-color-campo code { font-size: var(--bw-fs-sm); color: var(--bw-text-muted); }

/* Cuadro "Aa" de la tabla de contraste: se pinta con los colores reales
   del par, para poder juzgarlo a ojo ademas de por el numero. */
.bw-muestra {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 24px;
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-sm);
  font-weight: var(--bw-fw-semibold);
}


/* ============================================================================
   17. PIEL v2 — SIDEBAR ANCHO, CABECERA CON PESTANAS Y TABLAS
   ----------------------------------------------------------------------------
   Capa aditiva sobre estilos.css. Se sobreescriben aqui los componentes
   que cambian de aspecto en la Fase 1.B en lugar de editar la hoja del
   design system, para que estilos.css siga siendo portable y para poder
   ver de un vistazo QUE cambia la re-tematizacion.
   ========================================================================== */

:root {
  --bw-sidebar-w: 208px;
  --bw-sidebar-w-min: 56px;   /* plegado: solo iconos */
}

/* ---- Sidebar: de 65px solo-iconos a 208px icono+texto ---- */
.bw-sidebar {
  width: var(--bw-sidebar-w);
  align-items: stretch;
  padding: 0 0 var(--bw-sp-4);
  background: var(--bw-estructural);
  border-right: 0;
  gap: 0;
  transition: width .15s ease;
}

.bw-sidebar__centro {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-4);
  background: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
  min-height: 56px;
}
.bw-sidebar__centro-etiqueta {
  display: block;
  font-size: var(--bw-fs-xs);
  text-transform: uppercase;
  letter-spacing: .6px;
  opacity: .85;
}
.bw-sidebar__centro-nombre {
  display: block;
  font-weight: var(--bw-fw-semibold);
  font-size: var(--bw-fs-md);
  line-height: 1.2;
  /* El nombre del centro puede ser largo; recortar es preferible a
     empujar el menu entero. El title del elemento da el completo. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 130px;
}

.bw-sidebar__toggle {
  margin-left: auto;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  font-size: var(--bw-fs-lg);
  line-height: 1;
  padding: 4px 6px;
  border-radius: var(--bw-radius-sm);
}
.bw-sidebar__toggle:hover { background: rgba(0, 0, 0, .12); }

/* El enlace de menu deja de ser un cuadrado de icono */
.bw-sidebar .bw-nav-icon {
  width: auto;
  height: auto;
  justify-content: flex-start;
  gap: var(--bw-sp-3);
  padding: 10px var(--bw-sp-4);
  margin: 0;
  border-radius: 0;
  color: rgba(255, 255, 255, .82);
  font-size: var(--bw-fs-md);
}
.bw-sidebar .bw-nav-icon:hover {
  background: rgba(255, 255, 255, .10);
  color: #fff;
}
.bw-sidebar .bw-nav-icon.is-active {
  background: rgba(255, 255, 255, .16);
  color: #fff;
  font-weight: var(--bw-fw-semibold);
}
.bw-sidebar .bw-nav-icon.is-active::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  height: auto;
  border-radius: 0;
  background: var(--bw-principal);
}
.bw-nav-icon__icono {
  width: 18px;
  text-align: center;
  flex: 0 0 18px;
  font-size: 15px;
}
.bw-nav-icon__texto { white-space: nowrap; }

/* Con el menu plegado el texto desaparece y el tooltip vuelve a hacer
   falta; abierto estorba, porque el nombre ya se lee. */
.bw-sidebar .bw-nav-icon__tip { display: none; }

.bw-app.is-plegado { grid-template-columns: var(--bw-sidebar-w-min) var(--bw-subnav-w) 1fr; }
.bw-app.is-plegado.bw-app--no-subnav { grid-template-columns: var(--bw-sidebar-w-min) 1fr; }
.bw-app.is-plegado .bw-sidebar { width: var(--bw-sidebar-w-min); }
.bw-app.is-plegado .bw-nav-icon__texto,
.bw-app.is-plegado .bw-sidebar__centro-texto { display: none; }
.bw-app.is-plegado .bw-sidebar .bw-nav-icon { justify-content: center; padding-left: 0; padding-right: 0; }
.bw-app.is-plegado .bw-sidebar__centro { justify-content: center; padding-left: 0; padding-right: 0; }
.bw-app.is-plegado .bw-sidebar .bw-nav-icon__tip { display: block; }

/* ---- Cabecera de pagina: banda de color con pestanas ---- */
.bw-banda {
  background: var(--bw-apoyo-relleno);
  color: var(--bw-apoyo-sobre);
  padding: var(--bw-sp-4) var(--bw-sp-5) 0;
  margin: calc(var(--bw-sp-5) * -1) calc(var(--bw-sp-5) * -1) var(--bw-sp-5);
}
.bw-banda__fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-4);
  flex-wrap: wrap;
  padding-bottom: var(--bw-sp-3);
}
.bw-banda__titulo {
  margin: 0;
  font-size: var(--bw-fs-2xl);
  color: inherit;
}
.bw-banda__pestanas {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.bw-banda__pestana {
  display: inline-block;
  padding: 7px var(--bw-sp-4);
  border-radius: var(--bw-radius-md) var(--bw-radius-md) 0 0;
  background: rgba(255, 255, 255, .16);
  color: inherit;
  text-decoration: none;
  font-size: var(--bw-fs-md);
  line-height: 1.3;
}
.bw-banda__pestana:hover { background: rgba(255, 255, 255, .28); }
.bw-banda__pestana.is-active {
  background: var(--bw-bg);
  color: var(--bw-principal-text);
  font-weight: var(--bw-fw-semibold);
}

/* ---- Tablas: cabecera fija de color y pie con recuento ---- */
.bw-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
  border-bottom: 0;
}
.bw-table thead th:first-child { border-top-left-radius: var(--bw-radius-md); }
.bw-table thead th:last-child  { border-top-right-radius: var(--bw-radius-md); }
.bw-table th a { color: inherit; }
.bw-table th a:hover { color: inherit; text-decoration: underline; }
.bw-table th a.is-sorted .bw-table__sort { color: inherit; }

.bw-table__pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-4);
  flex-wrap: wrap;
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border: 1px solid var(--bw-border);
  border-top: 0;
  border-radius: 0 0 var(--bw-radius-md) var(--bw-radius-md);
  background: var(--bw-bg-100);
  font-size: var(--bw-fs-md);
  color: var(--bw-text-muted);
}

/* La columna de acciones se define UNA sola vez, mas abajo. Aqui vivia
   un width:50px de una version anterior que contradecia al width:1% de
   ese bloque: dos reglas peleando por el mismo ancho. */

/* ---- Iconos ---- */
.bw-icono { width: 1.1em; text-align: center; }

@media (max-width: 900px) {
  /* En movil el menu ancho se come la pantalla: se pliega siempre. */
  .bw-app,
  .bw-app--no-subnav { grid-template-columns: var(--bw-sidebar-w-min) 1fr; }
  .bw-sidebar { width: var(--bw-sidebar-w-min); }
  .bw-nav-icon__texto,
  .bw-sidebar__centro-texto { display: none; }
  .bw-sidebar .bw-nav-icon { justify-content: center; padding-left: 0; padding-right: 0; }
  .bw-sidebar__centro { justify-content: center; padding-left: 0; padding-right: 0; }
  .bw-banda { margin-left: calc(var(--bw-sp-4) * -1); margin-right: calc(var(--bw-sp-4) * -1); }
}

/* El logo hereda de estilos.css un cuadrado oscuro de 38px pensado para
   el sidebar blanco de 65px. Sobre la banda de color del centro sobra el
   fondo: basta el icono. */
.bw-sidebar__centro .bw-sidebar__logo {
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  margin: 0;
  background: none;
  color: inherit;
  font-size: 18px;
  border-radius: 0;
}
.bw-sidebar__centro .bw-sidebar__logo:hover { background: none; }

/* El separador del sidebar viejo sobra: ahora separa la banda del centro. */
.bw-sidebar__sep { display: none; }

/* En movil el submenu se abre con su boton; en escritorio no hace falta. */
@media (min-width: 901px) {
  .bw-subnav-toggle { display: none; }
}

/* El nombre del centro tiene que CEDER espacio: con un max-width fijo,
   entre logo, nombre y boton se pasaban de los 208px y el boton de
   plegar quedaba cortado contra el borde. min-width:0 es lo que permite
   que un hijo flexible se encoja por debajo de su contenido. */
.bw-sidebar__centro-texto { flex: 1 1 auto; min-width: 0; }
.bw-sidebar__centro-nombre { max-width: none; }
.bw-sidebar__toggle { flex: 0 0 auto; }

/* ----------------------------------------------------------------------------
   Sidebar en BLANCO.

   Se mantiene el ancho y la estructura; cambia el fondo. Con fondo claro
   el texto pasa a ser oscuro y el elemento activo ya no puede marcarse
   con un velo blanco translucido: se usa el tono suave de la marca mas la
   barra lateral de color, que es lo que se ve tambien con el menu
   plegado.

   Los colores de texto salen de --bw-*-text, que Domain\Tema ya oscurece
   hasta cumplir AA sobre blanco. Aqui el fondo ES blanco, asi que esas
   variables valen tal cual.
   -------------------------------------------------------------------------- */
.bw-sidebar {
  background: var(--bw-white);
  border-right: 1px solid var(--bw-border);
}

.bw-sidebar__centro {
  background: var(--bw-white);
  color: var(--bw-text);
  border-bottom: 1px solid var(--bw-border);
}
.bw-sidebar__centro .bw-sidebar__logo { color: var(--bw-principal-text); }
.bw-sidebar__centro-etiqueta { color: var(--bw-text-muted); opacity: 1; }
.bw-sidebar__toggle { color: var(--bw-text-muted); }
.bw-sidebar__toggle:hover { background: var(--bw-bg-200); color: var(--bw-text); }

.bw-sidebar .bw-nav-icon { color: var(--bw-text); }
.bw-sidebar .bw-nav-icon:hover {
  background: var(--bw-bg-200);
  color: var(--bw-text);
}
.bw-sidebar .bw-nav-icon.is-active {
  background: var(--bw-principal-soft);
  color: var(--bw-principal-text);
}
.bw-sidebar .bw-nav-icon.is-active .bw-nav-icon__icono { color: var(--bw-principal-text); }


/* ============================================================================
   18. ESTILO CLARO (referencia visual aportada por el cliente)
   ----------------------------------------------------------------------------
   Cambia la direccion de la piel: fuera las bandas de color macizo. El
   color se reserva para lo que hay que mirar —el elemento activo, los
   iconos de KPI, los badges de estado— y el resto es blanco sobre gris
   muy claro, con bordes finos.

   Se aparta a proposito de dos puntos del plan (§1.B.6 "banda de color
   secundario" y §1.B.7 "cabecera de tabla en color principal"): con la
   cabecera rellena de naranja, una tabla de ocho columnas es una franja
   de color que compite con los datos. Aqui la cabecera es gris y quien
   destaca es el contenido.
   ========================================================================== */

:root {
  --bw-bg-app: #f6f7f9;      /* fondo de la zona de contenido */
  --bw-radius-card: 12px;
}

/* ---- Lienzo ---- */
.bw-content { background: var(--bw-bg-app); }

/* ---- Tarjetas: blancas, borde fino, esquinas amplias ---- */
.bw-card {
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-card);
  box-shadow: none;
}
.bw-card__header {
  border-bottom: 1px solid var(--bw-border);
  padding: var(--bw-sp-4) var(--bw-sp-5);
}
.bw-card__title { font-size: var(--bw-fs-xl); font-weight: var(--bw-fw-semibold); }
.bw-card__body { padding: var(--bw-sp-5); }

/* ---- Sidebar: el activo es una pastilla solida ---- */
.bw-sidebar { padding-top: var(--bw-sp-2); }
.bw-sidebar .bw-nav-icon {
  margin: 2px var(--bw-sp-3);
  padding: 9px var(--bw-sp-3);
  border-radius: var(--bw-radius-md);
}
.bw-sidebar .bw-nav-icon.is-active {
  background: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
  font-weight: var(--bw-fw-semibold);
}
.bw-sidebar .bw-nav-icon.is-active .bw-nav-icon__icono { color: inherit; }
/* La barra lateral sobra cuando el propio elemento va relleno. */
.bw-sidebar .bw-nav-icon.is-active::before { display: none; }

/* ---- Submenu: mismo idioma que el sidebar ---- */
.bw-subnav { background: var(--bw-white); border-right: 1px solid var(--bw-border); }
.bw-subnav__link { border-radius: var(--bw-radius-md); margin: 1px var(--bw-sp-2); }
.bw-subnav__link.is-active {
  background: var(--bw-principal-soft);
  color: var(--bw-principal-text);
  font-weight: var(--bw-fw-semibold);
}

/* ---- Tablas: cabecera gris, no de color ---- */
.bw-table thead th {
  background: var(--bw-bg-200);
  color: var(--bw-text-muted);
  font-size: var(--bw-fs-sm);
  font-weight: var(--bw-fw-semibold);
  text-transform: uppercase;
  letter-spacing: .3px;
  border-bottom: 1px solid var(--bw-border);
}
.bw-table th a { color: var(--bw-text-muted); }
.bw-table th a:hover { color: var(--bw-principal-text); }

.bw-table-wrap {
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-card);
  overflow: hidden;
}
/* Dentro de una tarjeta la tabla no lleva su propio marco. */
.bw-card__body .bw-table-wrap { border: 0; border-radius: 0; }

/* ---- KPI: icono en cuadro de color a la izquierda ---- */
.bw-kpi {
  display: flex;
  align-items: flex-start;
  gap: var(--bw-sp-4);
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-card);
  padding: var(--bw-sp-4);
}
.bw-kpi__icono {
  width: 42px; height: 42px;
  flex: 0 0 42px;
  display: grid; place-items: center;
  border-radius: 10px;
  font-size: 17px;
}
.bw-kpi__label { color: var(--bw-text-muted); font-size: var(--bw-fs-md); margin: 0 0 2px; }
.bw-kpi__value { font-size: var(--bw-fs-3xl); font-weight: var(--bw-fw-bold); margin: 0; line-height: 1.1; }
.bw-kpi__trend { font-size: var(--bw-fs-sm); color: var(--bw-text-muted); margin: 4px 0 0; }
.bw-kpi__trend--sube { color: #1E7A3C; }
.bw-kpi__trend--baja { color: #B3341A; }

/* Las variantes de color pasan a tenir el fondo blanco: el color vive en
   el cuadro del icono, no en toda la tarjeta. */
.bw-kpi--teal,
.bw-kpi--blue,
.bw-kpi--orange,
.bw-kpi--purple,
.bw-kpi--yellow { background: var(--bw-white); }

.bw-kpi--teal   .bw-kpi__icono { background: var(--bw-teal-soft);   color: var(--bw-teal-text); }
.bw-kpi--blue   .bw-kpi__icono { background: #E7F0FE;               color: #1A4FA0; }
.bw-kpi--orange .bw-kpi__icono { background: var(--bw-principal-soft); color: var(--bw-principal-text); }
.bw-kpi--purple .bw-kpi__icono { background: #EFE9FB;               color: #4B2E86; }
.bw-kpi--yellow .bw-kpi__icono { background: var(--bw-acento-soft); color: var(--bw-acento-text); }

/* ---- Topbar: buscador redondeado ---- */
.bw-topbar { background: var(--bw-white); border-bottom: 1px solid var(--bw-border); }
.bw-topbar__title { font-size: var(--bw-fs-xl); font-weight: var(--bw-fw-semibold); }

/* ---- Badges de estado: pastilla suave ---- */
.bw-badge {
  border-radius: var(--bw-radius-full);
  padding: 3px 10px;
  font-size: var(--bw-fs-sm);
  font-weight: var(--bw-fw-medium);
}

/* ---- Botones: esquinas mas suaves ---- */
.bw-btn { border-radius: var(--bw-radius-md); }
.bw-btn--accent {
  background: var(--bw-principal-relleno);
  border-color: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
}
.bw-btn--accent:hover {
  background: var(--bw-principal-hover);
  border-color: var(--bw-principal-hover);
}

/* ---- Enlace de "ver todo" al pie de una tarjeta ---- */
.bw-card__pie {
  padding: var(--bw-sp-3) var(--bw-sp-5);
  border-top: 1px solid var(--bw-border);
}
.bw-card__pie a { color: var(--bw-principal-text); text-decoration: none; font-weight: var(--bw-fw-medium); }
.bw-card__pie a:hover { text-decoration: underline; }

/* ---- Modal remoto (formularios y subpaginas) ---- */
.bw-modal--ancho {
  width: min(920px, 94vw);
  /* El max-width:520px de .bw-modal recortaba esto y la clase "ancho" no
     ensanchaba nada: el TPV salia a 520px con los desplegables cortados
     a "El" y "Sin". */
  max-width: min(920px, 94vw);
  max-height: 90vh;
  overflow: auto;
  position: relative;
  padding: var(--bw-sp-5);
}
/* La X del modal remoto.

   Estaba en `top:10px; right:10px` sin fondo, y acababa montada sobre el
   borde del modal y pegada a los botones de la propia pagina —"Editar",
   en el detalle de una clase—. Un clic a un par de pixeles de distancia
   editaba en vez de cerrar.

   Ahora tiene su sitio: area de 36px, fondo propio para despegarse del
   contenido, y suficiente margen para que no toque nada. */
.bw-modal-remoto .bw-modal__close {
  position: absolute;
  top: var(--bw-sp-3);
  right: var(--bw-sp-3);
  z-index: 3;

  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  box-shadow: 0 1px 3px rgba(17, 17, 17, .08);
  transition: background-color var(--bw-transition), color var(--bw-transition);
}

.bw-modal-remoto .bw-modal__close:hover {
  background: var(--bw-red-soft);
  color: var(--bw-danger);
  border-color: var(--bw-danger);
}

/* Y el contenido deja libre esa esquina, para que ningun boton de la
   pagina cargada acabe debajo de la X. */
.bw-modal-remoto .bw-content-header,
.bw-modal-remoto .bw-modal__header { padding-right: 52px; }
.bw-modal-remoto__cargando { text-align: center; padding: var(--bw-sp-8); color: var(--bw-text-muted); }

/* Dentro del modal la pagina no necesita su cabecera de accion: el
   titulo ya lo da el propio contenido y los botones "Volver" sobran. */
.bw-modal-remoto .bw-content-header { margin-top: 0; }
.bw-modal-remoto .bw-content-actions .bw-btn--ghost { display: none; }

/* Con el modal abierto el fondo no se desplaza. */
body.bw-modal-remoto--abierto { overflow: hidden; }

/* Dentro del modal las columnas se estrechan pero NO se colapsan.
   Se escribio a una columna cuando el modal medía 520px de verdad —el
   max-width que lo recortaba—; a los 920 reales dos columnas caben, y
   forzar una sola dejaba el campo del IVA estirado a 800px para escribir
   "21%". Por debajo de 720 sí se apila: ahi ya no hay sitio. */
.bw-modal-remoto .bw-profile { gap: var(--bw-sp-4); }
@media (max-width: 720px) {
  .bw-modal-remoto .bw-profile { grid-template-columns: 1fr; }
}
.bw-modal-remoto .bw-layout-filtros { grid-template-columns: 1fr; }
.bw-modal-remoto .bw-form-row { grid-template-columns: 150px 1fr; }
.bw-modal-remoto .bw-card { border: 0; }
.bw-modal-remoto .bw-card__body { padding: var(--bw-sp-4) 0; }
.bw-modal-remoto .bw-card__header { padding-left: 0; padding-right: 0; }
.bw-modal-remoto .bw-kpi-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

@media (max-width: 700px) {
  .bw-modal-remoto .bw-form-row { grid-template-columns: 1fr; }
}


/* ============================================================================
   13. ACCIONES DE FILA COMO ICONOS

   Las tablas del panel llevaban botones con texto ("Editar", "Quitar",
   "Pausar", "Cancelar"). Con dos o tres acciones por fila la columna se
   comia media tabla, y en Cobros recurrentes —que tiene tres— se salia
   por encima de la columna de Estado. Ahora son iconos de 28px.

   El texto NO desaparece: va en title (raton) y en aria-label (lector de
   pantalla). Ver Core\Ui, que es quien pinta el marcado.
   ========================================================================== */
.bw-accion {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* min-width y no width: con el icono a 1.1rem el contenido pasaba de
     los 28px y las cajas se solapaban, dejando el ojo pegado al lapiz.
     Asi el boton nunca baja de 28 —sigue siendo comodo de pulsar— pero
     crece si el icono lo pide. */
  min-width: 30px; height: 30px;
  padding: 0 2px;
  border: 0;
  border-radius: var(--bw-radius-sm);
  background: none;
  color: var(--bw-text-muted);
  /* 1.1rem y no una variable de la escala de texto: estos iconos no son
     texto, y a la medida anterior costaba distinguir el ojo de la
     papelera de un vistazo en una tabla larga. */
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  transition: background-color .12s, color .12s;
}
.bw-accion:hover  { background: var(--bw-bg-200); color: var(--bw-text); }
.bw-accion:focus-visible {
  outline: 2px solid var(--bw-principal-relleno);
  outline-offset: 1px;
}
.bw-accion--peligro:hover { background: var(--bw-danger-soft, #fdecec); color: var(--bw-danger); }
.bw-accion--exito:hover   { background: var(--bw-success-soft, #e8f6ee); color: var(--bw-success); }

/* La columna de acciones ya no puede ser de ancho fijo: con tres iconos
   no caben en 50px y se montan sobre la celda de Estado. Se le deja el
   ancho minimo que pida su contenido (width:1% + nowrap es el truco
   clasico para "lo mas estrecha posible" en una tabla). */
.bw-table td.bw-table__actions,
.bw-table th.bw-table__actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}
/* La celda se queda como celda de tabla y son sus HIJOS los que se
   alinean en linea.

   Antes llevaba display:flex y eso la sacaba del modelo de columnas: el
   navegador le asignaba un sitio (679-711) y pintaba los iconos en otro
   (633-695), asi que el "0/2" del aforo aparecia debajo del ojo. El
   propio comentario anterior ya avisaba de que un th en flex rompia la
   tabla; en el td pasa lo mismo, solo que el sintoma es el solape en vez
   del desbordamiento. */
.bw-table td.bw-table__actions {
  padding-left: var(--bw-sp-4);   /* aire con la ultima columna de datos */
  /* Pegada al borde: el padding de 16px de la tabla a la derecha no
     separa de nada —es el final de la fila— y esos pixeles le hacen
     falta a las columnas de texto, que se partian en dos lineas. */
  padding-right: var(--bw-sp-2);
  font-size: 0;                   /* mata el espacio entre iconos en linea */
}
.bw-table th.bw-table__actions { padding-right: var(--bw-sp-2); }
.bw-table td.bw-table__actions > * { vertical-align: middle; }
.bw-table td.bw-table__actions .bw-accion { margin-left: 2px; }

/* En la cabecera de una tarjeta el icono acompana a un titulo grande, no
   a una fila de tabla: al mismo tamano que en la tabla se queda pequeno
   al lado del nombre del plan. */
.bw-card__header .bw-accion,
.bw-card__header .bw-estado { font-size: 1.35rem; }
.bw-card__header .bw-accion { min-width: 36px; height: 36px; }
/* Aire entre una cifra alineada a la derecha y los iconos de accion.

   El "0/2" del aforo acababa SOLAPADO con el primer icono (-14px), y a
   la vez sobraban 40px a la derecha de la tabla. Las dos cosas tienen la
   misma causa: con la columna de acciones a width:1% el navegador
   reparte el sobrante entre las columnas de texto y aprieta estas dos
   hasta que sus contenidos se pisan.

   Se le da a la cifra un ancho minimo propio —que la tabla ya no puede
   comprimir— y el hueco se lo queda ella en vez de quedarse muerto al
   final de la fila. */
.bw-table td.bw-table__num:has(+ td.bw-table__actions),
.bw-table th.bw-table__num:has(+ th.bw-table__actions) {
  padding-right: var(--bw-sp-5);
}

/* La columna de acciones deja de encogerse hasta el contenido: con
   width:1% el navegador la aprieta contra su vecina —el "0/2" acababa
   pintado ENCIMA del ojo— y a la vez dejaba hueco muerto al final de la
   fila. Con un ancho declarado ocupa lo suyo y el sobrante se reparte
   entre las columnas de texto, que es donde hace falta. */
.bw-table th.bw-table__actions { width: 1px; }
.bw-table td.bw-table__actions { white-space: nowrap; }
/* Los formularios de una sola accion no deben romper la fila de iconos. */
.bw-table td.bw-table__actions form { display: contents; }


/* ---- Estado binario como icono ---- */
/* Al mismo tamano que los iconos de accion: no son clicables —son
   indicadores de si/no— pero comparten fila con ellos, y a 15px se veian
   pequenos al lado de los de 1.1rem. */
.bw-estado { font-size: 1.1rem; line-height: 1; }
/* El formulario no ocupa: el icono debe quedar donde estaba, sin mover
   la fila ni romper la alineacion de la columna. */
.bw-estado-form { display: inline; }
.bw-estado--pulsable {
  background: none;
  border: 0;
  padding: 2px;
  cursor: pointer;
  border-radius: var(--bw-radius-sm);
  transition: background-color .12s, transform .12s;
}
/* Que se note que se puede pulsar: sin esto parece el mismo indicador de
   siempre y nadie lo intenta. */
.bw-estado--pulsable:hover { background: var(--bw-bg-200); transform: scale(1.1); }
.bw-estado--pulsable:focus-visible {
  outline: 2px solid var(--bw-principal-relleno);
  outline-offset: 1px;
}

.bw-estado--si     { color: var(--bw-success); }
.bw-estado--no     { color: var(--bw-danger); }
.bw-estado--neutro { color: var(--bw-text-muted); opacity: .55; }


/* ============================================================================
   14. ORDENAR POR CABECERA

   Lo aplica app.js a toda .bw-table que no lo tenga desactivado. El th se
   convierte en boton para que funcione con teclado; hereda el color de la
   cabecera de color, asi que no se ve como un boton suelto.
   ========================================================================== */
.bw-orden {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}
.bw-table th.bw-table__num .bw-orden { justify-content: flex-end; }
.bw-orden:hover { text-decoration: underline; }
.bw-orden__flecha { font-size: 9px; opacity: .35; }
.bw-orden:hover .bw-orden__flecha { opacity: .7; }
th[aria-sort] .bw-orden__flecha { opacity: 1; }
.bw-orden:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }


/* ============================================================================
   15. BUSCADOR PREDICTIVO (apuntar alumno a la clase)

   Los resultados se pintaban en un div suelto que empujaba el resto del
   formulario hacia abajo segun cuantos hubiera. Ahora es un desplegable
   flotante de 5 como mucho, anclado al campo.
   ========================================================================== */
.bw-autocompletar { position: relative; }
.bw-autocompletar__lista {
  position: absolute;
  left: 0; right: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px;
  list-style: none;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-md);
  box-shadow: var(--bw-shadow-md);
  z-index: var(--bw-z-popover);
  max-height: 260px;
  overflow-y: auto;
}
.bw-autocompletar__lista[hidden] { display: none; }
.bw-autocompletar__opcion {
  display: block; width: 100%;
  padding: var(--bw-sp-2) var(--bw-sp-3);
  border: 0; border-radius: var(--bw-radius-sm);
  background: none;
  font: inherit; color: var(--bw-text);
  text-align: left; cursor: pointer;
}
.bw-autocompletar__opcion:hover,
.bw-autocompletar__opcion.is-activa { background: var(--bw-bg-200); }
.bw-autocompletar__opcion strong { display: block; font-weight: var(--bw-fw-semibold); }
.bw-autocompletar__opcion span { font-size: var(--bw-fs-sm); color: var(--bw-text-muted); }
.bw-autocompletar__vacio {
  padding: var(--bw-sp-2) var(--bw-sp-3);
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
}


/* ---- Cerrar sesion al pie del menu lateral ----
   Estaba solo detras del avatar de la esquina, que es un sitio que hay
   que descubrir. Al final del menu y separado del resto esta donde se
   busca. El del avatar se mantiene: quien ya lo usa no lo pierde. */
.bw-sidebar__pie {
  margin-top: auto;
  padding-top: var(--bw-sp-2);
  border-top: 1px solid rgba(255, 255, 255, .12);
}
.bw-sidebar__pie form { display: block; }
.bw-sidebar__pie .bw-nav-icon {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--bw-fs-md);
  cursor: pointer;
  text-align: left;
}

/* ============================================================
   Portada publica
   ============================================================
   Editorial: hero a pantalla completa con la foto de fondo,
   titulares en Cinzel (serif romana en versales) y secciones
   centradas con filete. Los acentos salen de las variables de
   marca que Tema::estilosInline() saca de businesses.settings,
   asi que la portada sigue repintandose desde la ficha del
   centro sin tocar este fichero. */

.bw-portal__main:has(.bw-hero) {
  /* El hero se sale del ancho del contenedor para ocupar todo el
     alto de la ventana; el resto de secciones mantienen su caja. */
  max-width: none;
  padding: 0;
}

/* --- Hero --- */

.bw-hero {
  position: relative;
  min-height: min(88vh, 760px);
  display: flex;
  align-items: center;
  overflow: hidden;
  margin-bottom: var(--bw-sp-9);
}

.bw-hero__fondo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Velo en degradado: sin el, el titular blanco se pierde sobre las
   zonas claras de la foto y deja de leerse. */
.bw-hero__velo {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(17, 17, 17, .78) 0%, rgba(17, 17, 17, .55) 45%, rgba(17, 17, 17, .25) 100%);
}

.bw-hero__contenido {
  position: relative;
  width: min(1180px, 100%);
  margin: 0 auto;
  padding: var(--bw-sp-8) var(--bw-sp-6);
  color: #fff;
}

.bw-hero__eyebrow {
  margin: 0 0 var(--bw-sp-4);
  font-size: var(--bw-fs-sm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .82);
}

.bw-hero__titulo {
  margin: 0 0 var(--bw-sp-4);
  font-family: "Cinzel", Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(2.4rem, 6vw, 4.1rem);
  line-height: 1.08;
  letter-spacing: .04em;
  text-transform: uppercase;
  max-width: 16ch;
}

/* El remate -- la ultima palabra del titular -- baja de linea y va en
   cursiva: es el gesto que ordena la portada. */
.bw-hero__titulo em {
  display: block;
  font-style: italic;
  font-weight: 400;
  color: var(--bw-principal);
}

.bw-hero__entradilla {
  margin: 0 0 var(--bw-sp-6);
  font-size: var(--bw-fs-lg);
  line-height: 1.6;
  max-width: 46ch;
  color: rgba(255, 255, 255, .92);
}

.bw-hero__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-3);
}

/* --- Botones pildora --- */

.bw-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 30px;
  border-radius: var(--bw-radius-pill);
  font-size: var(--bw-fs-sm);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color var(--bw-transition), color var(--bw-transition), border-color var(--bw-transition);
}

.bw-pill--claro { background: #fff; color: #1d1d1d; }
.bw-pill--claro:hover { background: rgba(255, 255, 255, .86); }

.bw-pill--fantasma {
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
}
.bw-pill--fantasma:hover { background: rgba(255, 255, 255, .26); }

.bw-pill--marca {
  background: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
}
.bw-pill--marca:hover { background: var(--bw-principal-hover); }

.bw-pill--borde {
  color: var(--bw-text);
  border-color: var(--bw-border-strong);
}
.bw-pill--borde:hover { background: var(--bw-bg-100); }

/* --- Secciones --- */

.bw-sec {
  width: min(1180px, 100%);
  margin: 0 auto var(--bw-sp-9);
  padding: 0 var(--bw-sp-5);
}

.bw-sec__cabecera {
  text-align: center;
  margin-bottom: var(--bw-sp-7);
}

.bw-sec__titulo {
  margin: 0;
  font-family: "Cinzel", Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.6rem, 3.2vw, 2.4rem);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bw-navy-2);
}

.bw-sec__titulo em {
  font-style: italic;
  font-weight: 400;
  color: var(--bw-principal-text);
}

.bw-sec__filete {
  display: block;
  width: 72px;
  height: 2px;
  margin: var(--bw-sp-3) auto 0;
  background: var(--bw-principal-relleno);
}

.bw-sec__categoria {
  margin: 0 0 var(--bw-sp-4);
  text-align: center;
  font-size: var(--bw-fs-sm);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bw-text-muted);
}

/* Franja oscura: rompe la sucesion de secciones claras y da a la
   pagina el ritmo del sitio de referencia. */
.bw-sec--oscura {
  width: 100%;
  max-width: none;
  background: #1d1d1d;
  color: #fff;
  padding: var(--bw-sp-8) var(--bw-sp-5);
}

.bw-sec--oscura .bw-sec__titulo { color: #fff; }

/* --- Tarjetas de servicio --- */

.bw-tarjetas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--bw-sp-5);
  margin-bottom: var(--bw-sp-6);
}

.bw-tarjeta {
  display: flex;
  flex-direction: column;
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-xl);
  padding: var(--bw-sp-6) var(--bw-sp-5);
  text-align: center;
  text-decoration: none;
  color: inherit;
  box-shadow: 0 1px 2px rgba(17, 17, 17, .04);
  transition: transform var(--bw-transition), box-shadow var(--bw-transition), border-color var(--bw-transition);
}

.bw-tarjeta:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px rgba(17, 17, 17, .10);
  border-color: var(--bw-principal-borde);
}

.bw-tarjeta__nombre {
  margin: 0 0 var(--bw-sp-3);
  font-family: "Cinzel", Georgia, serif;
  /* Mas cuerpo que antes (fs-lg): el nombre del servicio es lo primero
     que se lee de la tarjeta y competia de tu a tu con la descripcion. */
  font-size: var(--bw-fs-xl);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--bw-navy-2);
}

.bw-tarjeta__texto {
  margin: 0 0 var(--bw-sp-4);
  color: var(--bw-text-muted);
  line-height: 1.6;
  flex: 1;
}

.bw-tarjeta__meta {
  margin: 0 0 var(--bw-sp-2);
  font-size: var(--bw-fs-sm);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bw-text-muted);
}

.bw-tarjeta__precio {
  margin: 0 0 var(--bw-sp-4);
  font-family: "Cinzel", Georgia, serif;
  font-size: var(--bw-fs-xl);
  font-weight: 700;
  color: var(--bw-navy-2);
}

.bw-tarjeta__cta {
  font-size: var(--bw-fs-sm);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bw-principal-text);
}

/* --- Horario --- */

.bw-dias {
  width: min(720px, 100%);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.bw-dia {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--bw-sp-4);
  padding: var(--bw-sp-3) var(--bw-sp-2);
  border-bottom: 1px solid rgba(255, 255, 255, .14);
}

.bw-dia__nombre { letter-spacing: .06em; text-transform: uppercase; font-size: var(--bw-fs-md); }
.bw-dia__horas { font-variant-numeric: tabular-nums; }

.bw-dia.is-cerrado { color: rgba(255, 255, 255, .5); }

/* El dia de hoy se marca con el color de la marca, no solo con la
   palabra: quien mira de reojo encuentra su linea sin leer. */
.bw-dia.is-hoy { color: var(--bw-principal); }

.bw-dia__hoy {
  display: inline-block;
  margin-left: var(--bw-sp-2);
  padding: 2px 10px;
  border-radius: var(--bw-radius-pill);
  background: var(--bw-principal-relleno);
  color: var(--bw-principal-sobre);
  font-size: var(--bw-fs-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* --- Llamada final y contacto --- */

.bw-cta {
  width: min(1180px, 100%);
  margin: 0 auto var(--bw-sp-9);
  padding: var(--bw-sp-8) var(--bw-sp-5);
  text-align: center;
  background: var(--bw-bg-100);
  border-radius: var(--bw-radius-xl);
}

.bw-cta__texto { margin: var(--bw-sp-4) 0 var(--bw-sp-6); color: var(--bw-text-muted); }

.bw-cta__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-3);
  justify-content: center;
}

.bw-cta__pie { margin: var(--bw-sp-5) 0 0; font-size: var(--bw-fs-md); }

.bw-contacto {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--bw-sp-8);
  margin: 0;
  text-align: center;
}

.bw-contacto dt {
  font-size: var(--bw-fs-sm);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bw-text-muted);
  margin-bottom: var(--bw-sp-2);
}

.bw-contacto dd { margin: 0; font-size: var(--bw-fs-lg); }

@media (max-width: 760px) {
  .bw-hero { min-height: 74vh; }
  .bw-hero__contenido { padding: var(--bw-sp-7) var(--bw-sp-4); }
  .bw-hero__titulo { max-width: none; }
  .bw-hero__acciones .bw-pill { flex: 1 1 100%; }
  .bw-contacto { gap: var(--bw-sp-5); }
}

@media (prefers-reduced-motion: reduce) {
  .bw-tarjeta { transition: none; }
  .bw-tarjeta:hover { transform: none; }
}

/* La cabecera se funde con el hero SOLO en la portada: el resto del
   portal la sigue queriendo blanca y con su linea. El :has() mira si
   la pagina trae hero, asi que no hace falta una clase en el body. */
body:has(.bw-hero) .bw-portal__header {
  position: absolute;
  inset: 0 0 auto;
  background: transparent;
  border-bottom: 0;
}

body:has(.bw-hero) .bw-portal__logo,
body:has(.bw-hero) .bw-portal__nav a:not(.bw-btn) {
  color: #fff;
}

body:has(.bw-hero) .bw-portal__logo-mark {
  background: rgba(255, 255, 255, .18);
  color: #fff;
}

/* El outline trae fondo blanco propio: sin anularlo, el texto en
   blanco desaparecia y quedaba un rectangulo vacio sobre la foto. */
body:has(.bw-hero) .bw-portal__nav .bw-btn--outline {
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border-color: rgba(255, 255, 255, .6);
}

body:has(.bw-hero) .bw-portal__nav .bw-btn--outline:hover {
  background: rgba(255, 255, 255, .28);
  color: #fff;
}

/* Una sola tarjeta no debe estirarse a lo ancho de la fila: con
   auto-fit, "Terapias" ocupaba el ancho completo y parecia otra cosa
   distinta de las de arriba. */
.bw-tarjetas { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }

/* Paginas sueltas del portal: una columna de lectura, no el ancho
   completo de la pantalla. Mas de unos 70 caracteres por linea y el ojo
   pierde el renglon al volver. */
.bw-pagina {
  max-width: 68ch;
  margin: 0 auto;
  line-height: 1.75;
}

.bw-pagina p { margin: 0 0 var(--bw-sp-4); }

/* Valorar una clase desde Mis reservas. */
.bw-valorar {
  margin-top: var(--bw-sp-6);
  padding: var(--bw-sp-5);
  background: var(--bw-bg-100);
  border-radius: var(--bw-radius-xl);
}

.bw-valorar__clase {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-3);
  align-items: center;
  padding: var(--bw-sp-3) 0;
  border-bottom: 1px solid var(--bw-border);
}

.bw-valorar__clase:last-of-type { border-bottom: 0; }

/* Las estrellas son botones de radio disfrazados: se navegan con el
   teclado y funcionan sin JavaScript. */
.bw-estrellas { display: inline-flex; flex-direction: row-reverse; gap: 2px; }

.bw-estrellas input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.bw-estrellas label {
  cursor: pointer;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--bw-border-strong);
  transition: color var(--bw-transition);
}

/* El hermano anterior en el DOM es la estrella de la izquierda, por el
   row-reverse: al pasar por la 4 se encienden tambien 3, 2 y 1. */
.bw-estrellas input:checked ~ label,
.bw-estrellas label:hover,
.bw-estrellas label:hover ~ label { color: var(--bw-principal); }

.bw-estrellas input:focus-visible + label { outline: 2px solid var(--bw-principal); outline-offset: 2px; }

/* Opiniones de la portada. */
.bw-opiniones__nota {
  margin: var(--bw-sp-3) 0 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: var(--bw-fs-lg);
}

.bw-opinion {
  margin: 0;
  padding: var(--bw-sp-6) var(--bw-sp-5);
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-xl);
  text-align: center;
}

.bw-opinion__estrellas { margin: 0 0 var(--bw-sp-3); color: var(--bw-principal); letter-spacing: 2px; }
.bw-opinion__vacias { color: var(--bw-border-strong); }
.bw-opinion__texto { margin: 0 0 var(--bw-sp-4); line-height: 1.7; font-style: italic; }

.bw-opinion__firma {
  font-size: var(--bw-fs-sm);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bw-text-muted);
}


/* ---- Dos campos en la misma linea (portal) ----
   `.bw-form-row` de estilos.css es la rejilla del PANEL: `160px 1fr`, con
   la etiqueta a la izquierda y el campo a la derecha, y `align-items:
   center`. Reutilizarla aqui para poner dos campos juntos daba dos
   defectos a la vez: anchos distintos (160px contra el resto) y los
   campos descuadrados en vertical, porque al centrar cada columna por
   separado, la que lleva texto de ayuda debajo empuja a su pareja.

   Aqui las dos columnas son iguales y se alinean por arriba, asi que los
   campos quedan a la misma altura lleve ayuda una, las dos o ninguna. */
.bw-campos-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: var(--bw-sp-4);
  margin-bottom: var(--bw-sp-4);
}

/* Las etiquetas del portal van encima del campo, no al lado. */
.bw-campos-2 > div { display: flex; flex-direction: column; }
.bw-campos-2 .bw-input { width: 100%; }

@media (max-width: 560px) {
  /* Dos campos de 150px no dejan leer ni lo que se escribe. */
  .bw-campos-2 { grid-template-columns: 1fr; gap: var(--bw-sp-3); }
}




/* ---- Portada: mas aire y jerarquia ----
   La portada anterior contaba lo justo y lo contaba pequeño: las tarjetas
   de servicio eran cajas de 260px con el precio en texto normal, y entre
   seccion y seccion habia el mismo hueco que entre dos parrafos. El
   resultado se leia como un listado, no como un escaparate. */

/* Rejilla mas generosa: tres columnas como mucho, y tarjetas que no
   bajan de 300px para que quepa el precio en grande. */
.bw-tarjetas {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
}

/* Una sola tarjeta no debe estirarse a todo el ancho: queda como un
   cartel y desequilibra la pagina. */
.bw-tarjetas:has(> :only-child) { max-width: 420px; }

.bw-tarjeta { padding: var(--bw-sp-7) var(--bw-sp-6); }

/* El precio es la respuesta a la pregunta con la que llega el visitante,
   asi que se lee desde lejos. */
.bw-tarjeta__precio {
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.9rem, 3.4vw, 2.5rem);
  font-weight: 700;
  line-height: 1.1;
  color: var(--bw-navy-2);
  margin: var(--bw-sp-2) 0 var(--bw-sp-4);
}

/* La llamada deja de ser un texto suelto y pasa a leerse como accion. */
.bw-tarjeta__cta {
  display: inline-block;
  padding-top: var(--bw-sp-3);
  border-top: 1px solid var(--bw-border);
  font-size: var(--bw-fs-sm);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bw-principal-text);
}

/* Aire entre secciones: es lo que separa un escaparate de un listado. */
.bw-sec { padding-block: var(--bw-sp-9); }
.bw-sec__cabecera { margin-bottom: var(--bw-sp-7); }

/* ---- Secciones de contenido (metodo, equipamiento, resultados) ----
   Titular a la izquierda y texto a la derecha: el mismo gesto que usa el
   sector para no dejar una columna de texto centrada de 900px, que es
   incomodo de leer. En movil se apila. */
.bw-bloque {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(280px, 1.15fr);
  gap: var(--bw-sp-7);
  align-items: start;
  max-width: 1100px;
  margin: 0 auto;
}

.bw-bloque__titulo {
  margin: 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: clamp(1.9rem, 4vw, 3rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--bw-navy-2);
}

/* El remate en cursiva y en color, igual que el titular del hero: es el
   gesto que hila toda la portada. */
.bw-bloque__titulo em {
  display: block;
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  color: var(--bw-principal-text);
}

.bw-bloque__texto {
  margin: 0;
  font-size: var(--bw-fs-lg);
  line-height: 1.7;
  color: var(--bw-text-muted);
}

/* Los puntos: rejilla que cabe en dos filas de dos, o cuatro seguidos. */
.bw-puntos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--bw-sp-5);
  max-width: 1100px;
  margin: var(--bw-sp-7) auto 0;
}

.bw-punto {
  padding: var(--bw-sp-5);
  background: var(--bw-white);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-xl);
}

.bw-punto__rotulo {
  margin: 0 0 var(--bw-sp-2);
  font-family: "Cinzel", Georgia, serif;
  font-size: var(--bw-fs-lg);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--bw-navy-2);
}

.bw-punto__texto {
  margin: 0;
  line-height: 1.6;
  color: var(--bw-text-muted);
}

/* Sobre fondo oscuro los puntos no llevan caja: el contraste ya los
   separa, y una caja blanca ahi parte la banda en trozos. */
.bw-sec--oscura .bw-punto {
  background: transparent;
  border-color: rgba(255, 255, 255, .18);
}
.bw-sec--oscura .bw-punto__rotulo { color: #fff; }
.bw-sec--oscura .bw-punto__texto,
.bw-sec--oscura .bw-bloque__texto { color: rgba(255, 255, 255, .78); }
.bw-sec--oscura .bw-bloque__titulo { color: #fff; }

@media (max-width: 860px) {
  /* El titular encima del texto: en una columna estrecha, dos columnas
     de 280px dejan lineas de cuatro palabras. */
  .bw-bloque { grid-template-columns: 1fr; gap: var(--bw-sp-4); }
}

@media (max-width: 560px) {
  .bw-sec { padding-block: var(--bw-sp-7); }
  .bw-tarjeta { padding: var(--bw-sp-6) var(--bw-sp-5); }
}



/* ---- Cabecera de la lista de asistentes ----
   Dos botones que eligen el orden. Se alinean con las filas de abajo
   reservando el mismo hueco para el numero. */
.bw-asistentes__cabecera {
  display: flex;
  align-items: center;
  /* Los botones NO crecen: sin esto el flex reparte el ancho sobrante
     entre ellos y el subrayado del activo se estira media fila mas alla
     de la palabra. */
  justify-content: flex-start;
  gap: var(--bw-sp-5);
  padding: 0 var(--bw-sp-2) var(--bw-sp-2);
  border-bottom: 1px solid var(--bw-border);
  margin-bottom: var(--bw-sp-2);
}

.bw-asistentes__cabecera .bw-asistente__num {
  font-size: var(--bw-fs-sm);
  color: var(--bw-text-muted);
  text-transform: uppercase;
  letter-spacing: .06em;
}

/* `bw-orden` a secas ya existe para las cabeceras de tabla ordenables, y
   lleva `width:100%`: reutilizar el nombre estiraba estos botones a 456px
   y el segundo quedaba debajo del primero, sin poder pulsarlo. */
.bw-orden-lista {
  flex: 0 0 auto;
  background: none;
  border: 0;
  padding: 2px 0;
  font: inherit;
  font-size: var(--bw-fs-sm);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--bw-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.bw-orden-lista:hover { color: var(--bw-text); }

/* El activo se subraya: hace falta saber por que esta ordenada la lista
   sin tener que deducirlo de los nombres. */
.bw-orden-lista.is-activo {
  color: var(--bw-text);
  font-weight: 600;
  border-bottom-color: var(--bw-principal);
}

/* En la espera el rotulo no es un boton: ese orden no se toca. */
.bw-orden-lista--fijo { cursor: default; }

/* ---- Ficha de tratamiento ----
   Cada sesion es un bloque con su cabecera, sus datos en rejilla y las
   observaciones debajo. Se separan con una linea y no con tarjetas: van
   dentro de una tarjeta y anidar cajas las hace ilegibles. */
.bw-ficha {
  padding: var(--bw-sp-4) 0;
  border-bottom: 1px solid var(--bw-border);
}
.bw-ficha:last-child { border-bottom: 0; padding-bottom: 0; }

.bw-ficha__cabecera {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bw-sp-2);
  margin-bottom: var(--bw-sp-2);
}

/* Los datos en pares etiqueta/valor: se leen de un vistazo y no hacen
   falta las cabeceras de una tabla para tres campos. */
.bw-ficha__datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--bw-sp-3);
  margin: 0 0 var(--bw-sp-2);
}
.bw-ficha__datos dt {
  font-size: var(--bw-fs-sm);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--bw-text-muted);
}
.bw-ficha__datos dd { margin: 2px 0 0; font-weight: 600; }

.bw-ficha__notas { margin: 0 0 var(--bw-sp-2); }


/* Tres columnas para definir un campo: nombre, tipo y opciones. La de
   opciones solo sirve para el tipo "lista", pero esconderla segun el
   desplegable pediria JavaScript para ahorrar una caja vacia. */
.bw-campos-ficha {
  display: grid;
  grid-template-columns: 1.4fr .8fr 1.6fr;
  gap: var(--bw-sp-2);
  margin-bottom: var(--bw-sp-2);
}

@media (max-width: 720px) {
  .bw-campos-ficha { grid-template-columns: 1fr; }
}

/* ---- Correo sin confirmar ----
   Ambar, no rojo: no es un error del alumno, es un paso que le falta.
   Persistente mientras no se resuelva, porque de eso depende poder
   reservar. */
.bw-verifica {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-3);
  margin-bottom: var(--bw-sp-4);
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border: 1px solid #f0c36d;
  border-left: 4px solid #e8a33d;
  border-radius: var(--bw-radius-lg);
  background: #fdf6e7;
}

.bw-verifica strong { display: block; color: #7a5312; }
.bw-verifica span { font-size: var(--bw-fs-sm); color: #7a5312; }

/* En la portada la cabecera es `position: absolute` para fundirse con el
   hero, asi que no ocupa sitio y el aviso se le metia debajo: se leia el
   texto pisando el logo y el menu. Aqui se le deja el hueco que la
   cabecera no reserva. Solo en la portada: en el resto del portal la
   cabecera es sticky y si ocupa su espacio. */
body:has(.bw-hero) .bw-verifica { margin-top: 72px; }

@media (max-width: 560px) {
  body:has(.bw-hero) .bw-verifica { margin-top: 64px; }
}

/* Y con el aviso puesto, la cabecera deja de tener la foto detras: el
   texto blanco que se funde con el hero quedaria blanco sobre blanco
   (1,1:1, ilegible). Cuando hay aviso vuelve a su aspecto normal. */
body:has(.bw-hero):has(.bw-verifica) .bw-portal__header {
  position: sticky;
  background: var(--bw-white);
  border-bottom: 1px solid var(--bw-border);
}

body:has(.bw-hero):has(.bw-verifica) .bw-portal__logo,
body:has(.bw-hero):has(.bw-verifica) .bw-portal__nav a:not(.bw-btn) {
  color: var(--bw-text);
}

body:has(.bw-hero):has(.bw-verifica) .bw-portal__logo-mark {
  background: var(--bw-navy-2);
  color: var(--bw-white);
}

/* Con la cabecera ocupando su sitio otra vez, el hueco extra sobra. */
body:has(.bw-hero):has(.bw-verifica) .bw-verifica { margin-top: 0; }

@media (max-width: 560px) {
  .bw-verifica { flex-direction: column; align-items: stretch; }
  .bw-verifica .bw-btn { width: 100%; }
}

/* ---- Control de privacidad flotante ----
   A la izquierda y a media altura: no estorba el contenido, no pelea con
   el banner de cookies (abajo) ni con la cabecera (arriba), y se alcanza
   desde cualquier pagina.

   Es un icono que se despliega al pasar el raton o al enfocarlo con el
   teclado. En reposo no dice nada porque no hay nada que decidir: solo
   tiene que estar ahi el dia que alguien se arrepienta. */
.bw-privacidad {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 55;          /* bajo el aviso (1200) y el banner (60) */
  margin: 0;
}

.bw-privacidad__boton {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-2);
  max-width: 44px;      /* solo el icono */
  padding: var(--bw-sp-3);
  border: 1px solid var(--bw-border);
  border-left: 0;
  border-radius: 0 var(--bw-radius-lg) var(--bw-radius-lg) 0;
  background: var(--bw-white);
  color: var(--bw-teal-text);
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  box-shadow: var(--bw-shadow-md);
  transition: max-width .18s ease, color .18s ease;
}

/* Desactivada: gris, para que el estado se lea de un vistazo. */
.bw-privacidad__boton.is-off { color: var(--bw-text-muted); }

.bw-privacidad__boton:hover,
.bw-privacidad__boton:focus-visible { max-width: 320px; }

.bw-privacidad__texto {
  font-size: var(--bw-fs-sm);
  color: var(--bw-text);
}

@media (max-width: 560px) {
  /* En movil el contenido manda: el icono baja de tamano y se queda
     arriba del banner de cookies, sin taparlo. */
  .bw-privacidad { top: auto; bottom: 96px; transform: none; }
  .bw-privacidad__boton { max-width: 40px; padding: var(--bw-sp-2); }
}

/* Quien prefiere no ver movimiento tampoco lo ve aqui. */
@media (prefers-reduced-motion: reduce) {
  .bw-privacidad__boton { transition: none; }
}

/* Aviso de analitica. Abajo y sin tapar la pagina: un banner que obliga a
   contestar antes de leer nada es justo lo que molesta de estos avisos. */
.bw-cookies {
  position: fixed;
  left: 50%;
  bottom: var(--bw-sp-4);
  transform: translateX(-50%);
  z-index: 60;
  width: min(680px, calc(100% - 2 * var(--bw-sp-4)));
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-4);
  align-items: center;
  padding: var(--bw-sp-4) var(--bw-sp-5);
  background: #1d1d1d;
  color: #fff;
  border-radius: var(--bw-radius-xl);
  box-shadow: 0 10px 40px rgba(17, 17, 17, .3);
}

/* El color va explicito y no heredado: `p { color: var(--bw-text) }` de
   estilos.css pinta TODOS los parrafos del azul oscuro principal, y una
   regla de elemento gana a la herencia del contenedor. Sin esto el texto
   salia #1C293B sobre #1d1d1d: casi ilegible.

   #f2f2f2 en vez de blanco puro: sobre negro, el blanco al 100% vibra y
   cansa en un bloque de tres lineas. Contraste 15,8:1, muy por encima del
   4,5:1 que pide WCAG AA. */
.bw-cookies__texto {
  flex: 1 1 300px;
  margin: 0;
  font-size: var(--bw-fs-md);
  line-height: 1.5;
  color: #f2f2f2;
}

/* Lo mismo para cualquier otro texto que caiga dentro del banner. */
.bw-cookies p,
.bw-cookies a { color: #f2f2f2; }
.bw-cookies a:hover { color: #fff; }

.bw-cookies__acciones { display: flex; gap: var(--bw-sp-2); }

/* El boton fantasma sobre fondo oscuro necesita su propio color. */
.bw-cookies .bw-btn--ghost { color: #fff; }
.bw-cookies .bw-btn--ghost:hover { background: rgba(255, 255, 255, .14); }

@media (max-width: 560px) {
  .bw-cookies { bottom: 0; border-radius: var(--bw-radius-xl) var(--bw-radius-xl) 0 0; width: 100%; }
  .bw-cookies__acciones { flex: 1 1 100%; }
  .bw-cookies__acciones .bw-btn { flex: 1; }
}


/* ---------------- Facturas del alumno ----------------
   `bw-deuda` es una barra de aviso EN LA PAGINA, no un modal: lo que se
   debe tiene que seguir visible mientras se mira la tabla, y un modal se
   cierra. Por eso no reutiliza `bw-aviso-modal`.

   El aviso no va solo por color: lleva el importe escrito al lado. Quien
   no distinga el ambar sigue leyendo "Tienes pendiente de pago 270 EUR". */
.bw-deuda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bw-sp-3);
  margin: 0 0 var(--bw-sp-4);
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border-left: 4px solid var(--bw-warning);
  border-radius: var(--bw-radius-md);
  background: #FBF7EF;
  color: var(--bw-text);
}

.bw-deuda form { margin: 0; }

/* Los botones de cada fila en linea, y envolviendo en movil en vez de
   desbordar la tabla. */
.bw-factura__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bw-sp-2);
  align-items: center;
}

.bw-factura__acciones form { margin: 0; }


/* El pie de la factura (base, impuestos, total) necesita despegarse de
   las lineas: sin la raya se lee como una linea mas del detalle, y el
   total parece otro concepto facturado. */
.bw-factura__totales td { border: 0; padding-top: var(--bw-sp-1); padding-bottom: var(--bw-sp-1); }
.bw-factura__totales tr:first-child td { border-top: 2px solid var(--bw-border, #d9d5cd); padding-top: var(--bw-sp-3); }
.bw-factura__totales .bw-factura__total td { padding-top: var(--bw-sp-2); font-size: var(--bw-fs-lg, 1.05rem); }


/* ============================================================================
   AGENDA DEL ALUMNO (portal)
   ========================================================================== */

/* Una fila por clase: hora | que y con quien | plazas | accion.
   Rejilla y no tabla porque en movil las cuatro partes se apilan, y una
   tabla ahi obliga a scroll lateral. */
.bw-agenda__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-3);
  margin-bottom: var(--bw-sp-4);
}

.bw-agenda__dia {
  margin: 0 0 var(--bw-sp-3);
  font-size: var(--bw-fs-lg);
  color: var(--bw-navy-2);
}

.bw-agenda__clase {
  display: grid;
  grid-template-columns: 64px 1fr auto auto;
  align-items: center;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-3);
  border: 1px solid var(--bw-border);
  border-left: 4px solid var(--bw-success);
  border-radius: var(--bw-radius-md);
  background: var(--bw-white);
  margin-bottom: var(--bw-sp-2);
}

/* La completa se marca en el borde ADEMAS de en la etiqueta: el color
   solo no vale para quien no lo distingue, y la etiqueta lo dice. */
.bw-agenda__clase--completa { border-left-color: var(--bw-warning); }

.bw-agenda__hora {
  font-size: var(--bw-fs-lg);
  font-weight: 600;
  color: var(--bw-navy-2);
}

.bw-agenda__datos { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bw-agenda__datos strong { overflow-wrap: anywhere; }

.bw-agenda__accion { display: flex; justify-content: flex-end; }

.bw-agenda__form {
  display: flex;
  align-items: center;
  gap: var(--bw-sp-2);
  margin: 0;
}

/* El desplegable de "con que lo pagas" no necesita tanto ancho como un
   campo de formulario normal, y a ancho completo empuja el boton fuera. */
.bw-agenda__form .bw-input { width: auto; min-width: 180px; max-width: 260px; }

/* ---- El modal de "te falta un bono" ---- */
.bw-contratar__lista { list-style: none; margin: var(--bw-sp-3) 0; padding: 0; }

.bw-contratar__opcion {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--bw-sp-3);
  padding: var(--bw-sp-3) 0;
  border-bottom: 1px solid var(--bw-border);
}

.bw-contratar__opcion:last-child { border-bottom: 0; }
.bw-contratar__opcion > span:first-child { display: flex; flex-direction: column; gap: 2px; }
.bw-contratar__opcion form { margin: 0; }

.bw-contratar__precio { font-weight: 600; white-space: nowrap; }

/* La opcion de pagarla suelta va al final y en tono menor: es la salida
   de quien no quiere comprar nada, no lo que se le propone primero. */
.bw-contratar__suelta {
  margin: var(--bw-sp-3) 0 0;
  padding-top: var(--bw-sp-3);
  border-top: 1px solid var(--bw-border);
  color: var(--bw-text-muted);
  font-size: var(--bw-fs-sm);
}

@media (max-width: 640px) {
  /* Apilado: con 390px las cuatro columnas dejan la accion fuera. */
  .bw-agenda__clase {
    grid-template-columns: auto 1fr;
    row-gap: var(--bw-sp-2);
  }

  .bw-agenda__plazas { grid-column: 2; justify-self: start; }

  .bw-agenda__accion {
    grid-column: 1 / -1;
    justify-content: stretch;
  }

  .bw-agenda__form { flex-wrap: wrap; width: 100%; }
  .bw-agenda__form .bw-input { width: 100%; max-width: none; }
  .bw-agenda__form .bw-btn { width: 100%; }
  .bw-agenda__accion > .bw-btn { width: 100%; }

  .bw-contratar__opcion {
    grid-template-columns: 1fr auto;
    row-gap: var(--bw-sp-2);
  }

  .bw-contratar__opcion form { grid-column: 1 / -1; }
  .bw-contratar__opcion form .bw-btn { width: 100%; }
}


/* ---------------- Reservar hora (cita individual) ---------------- */

/* El aviso de "ademas puedes pedir hora": va arriba de la agenda, con
   los servicios como botones para no obligar a leer y luego buscar. */
.bw-demanda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--bw-sp-3);
  margin: 0 0 var(--bw-sp-4);
  padding: var(--bw-sp-3) var(--bw-sp-4);
  border: 1px solid var(--bw-border);
  border-left: 4px solid var(--bw-teal, #0F766E);
  border-radius: var(--bw-radius-md);
  background: var(--bw-white);
}

.bw-demanda__servicios { display: flex; flex-wrap: wrap; gap: var(--bw-sp-2); }

/* Las horas libres, en rejilla: se busca una hora de un vistazo, no se
   lee una lista. */
.bw-hora__rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
  gap: var(--bw-sp-2);
}

.bw-hora__form { margin: 0; }

.bw-hora__hueco {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  padding: var(--bw-sp-3) var(--bw-sp-2);
  border: 1px solid var(--bw-border);
  border-radius: var(--bw-radius-md);
  background: var(--bw-white);
  color: var(--bw-text);
  font: inherit;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.bw-hora__hueco:hover,
.bw-hora__hueco:focus-visible {
  border-color: var(--bw-accent, #E8922B);
  background: #FBF7EF;
}

.bw-hora__hora { font-size: var(--bw-fs-lg); font-weight: 600; }
.bw-hora__quien { font-size: var(--bw-fs-sm); color: var(--bw-text-muted); }

.bw-hora__gente { display: flex; flex-wrap: wrap; gap: var(--bw-sp-2); }

@media (max-width: 640px) {
  .bw-demanda { flex-direction: column; align-items: stretch; }
  .bw-demanda__servicios .bw-btn { width: 100%; }
  .bw-hora__rejilla { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
}
