/* =========================================================================
   AppItaca — sistema de diseño
   Identidad visual tomada de itacajiujitsu.com: paleta monocroma (negro,
   blanco, grises, sin color de marca), Archivo para titulares en mayúsculas
   y Montserrat para el cuerpo de texto.

   Todos los colores salen de las variables de :root. El modo oscuro no es más
   que otro juego de valores para esas mismas variables (ver más abajo
   [data-tema="oscuro"]), así que cualquier color nuevo debe entrar como
   variable y no como literal: si no, se queda claro en las dos apariencias.
   ========================================================================= */

:root {
  color-scheme: light;

  --bg-light: #ffffff;
  --bg-white: #ffffff;
  --text-dark: #141414;
  --text-gray: #545454;

  --accent: #ffffff;
  --accent-soft: #bdbdbd;
  --accent-dark: #6f6f6f;
  --accent-ink: #5f5f5f;
  --surface-dark: #101010;
  --hairline: rgba(20, 20, 20, 0.10);

  /* Texto de los párrafos sobre .section-dark */
  --texto-invertido: #a8a5a0;

  /* Texto que debe quedar por detrás de todo lo demás: el «sin clases» de un
     día vacío, un distintivo apagado. Aparte de --accent-soft, que es el gris
     de los bordes de los campos: ese tono, dado la vuelta, no se lee. */
  --texto-tenue: #bdbdbd;

  /* Superficies de apoyo: fondos que se despegan un poco del papel */
  --superficie-suave: #f2f2f2;
  --superficie-inerte: #f4f4f4;
  --superficie-aviso: #fafafa;

  --boton-hover: #3d3d3d;
  --foco-halo: rgba(20, 20, 20, 0.25);
  --velo: rgba(20, 20, 20, 0.55);
  --sombra: 0 24px 60px rgba(20, 20, 20, 0.18);
  /* La bola del interruptor y su sombra. La sombra es de verdad una sombra en
     las dos apariencias: con --foco-halo, que en oscuro es blanco, quedaba un
     halo alrededor de la bola. */
  --switch-boton: #ffffff;
  --sombra-boton: 0 1px 3px rgba(20, 20, 20, 0.25);

  /* Estados: verde para lo confirmado, granate para lo que falla o destruye */
  --ok-bg: #eef3ee;
  --ok-fg: #23512f;
  --error-bg: #fbeeed;
  --error-fg: #8c1d18;
  --error-texto: #b3261e;
  --peligro: #8c1d18;
  --peligro-hover: #6f1613;
  --peligro-texto: #ffffff;
  --aviso-bg: #fdf8ec;
  --aviso-borde: #8c6d1f;

  --font-heading: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Montserrat', Helvetica, sans-serif;

  --nav-height: 72px;
  /* Alto de la barra de pestañas de móvil, sin contar la franja del gesto de
     inicio del sistema (safe-area-inset-bottom). En escritorio no hay barra. */
  --nav-inferior: 0px;

  --step-xs: clamp(0.75rem, 0.72rem + 0.15vw, 0.82rem);
  --step-sm: clamp(0.87rem, 0.84rem + 0.16vw, 0.95rem);
  --step-0: clamp(1rem, 0.97rem + 0.18vw, 1.09rem);
  --step-1: clamp(1.12rem, 1.06rem + 0.3vw, 1.3rem);
  --step-2: clamp(1.35rem, 1.2rem + 1vw, 2.1rem);
  --step-3: clamp(1.6rem, 1.1rem + 2.4vw, 3.4rem);

  --space-2xs: clamp(0.5rem, 0.45rem + 0.25vw, 0.75rem);
  --space-xs: clamp(0.75rem, 0.65rem + 0.5vw, 1.25rem);
  --space-sm: clamp(1.25rem, 1rem + 1vw, 2rem);
  --space-md: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  --space-lg: clamp(3rem, 2rem + 4vw, 6rem);

  --radius: 14px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Alto de los controles. Un input, un select y un button lo calculan de tres
     maneras distintas, así que puestos en la misma fila no coinciden solos: el
     número tiene que venir de fuera y ser el mismo para los tres.
     Normal = la línea de --step-0 (1.09rem x 1.5) + los dos paddings de 0.75rem
     + los dos bordes. Compacto = el alto que ya tenía .btn-sm, que es el que
     manda en los filtros de administración y en las tablas. */
  --control-alto: 3.25rem;
  --control-alto-sm: 2.5rem;

  /* Flecha de los desplegables. Va en un token porque un background-image no
     entiende currentColor y hace falta una por apariencia. Es el gris de
     --accent-ink; dentro de un data-URI la almohadilla se escribe %23. */
  --flecha-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235f5f5f' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
}

/* ---- Modo oscuro -------------------------------------------------------- */
/* La paleta es monocroma, así que el modo oscuro es la misma dada la vuelta:
   lo que era blanco pasa a negro y al revés. El atributo lo pone el layout con
   la preferencia guardada en la cuenta (Mi cuenta ▸ Ajustes), de modo que la
   página ya llega pintada y no hay parpadeo al cargar.
   Los negros no son #000: sobre negro puro el texto blanco deslumbra. Se usa
   el #101010 de las secciones oscuras de la marca, con las superficies un
   punto por encima para que se distingan del fondo. */

:root[data-tema="oscuro"] {
  color-scheme: dark;

  --bg-light: #101010;
  --bg-white: #171717;
  --text-dark: #f5f5f5;
  --text-gray: #a8a5a0;

  --accent: #141414;
  --accent-soft: #4d4d4d;
  --accent-dark: #8f8f8f;
  --accent-ink: #9a9a9a;
  /* La sección "oscura" es la que rompe el ritmo de la página: en modo oscuro
     esa es la clara. */
  --surface-dark: #f2f2f2;
  --hairline: rgba(255, 255, 255, 0.14);

  --texto-invertido: #545454;

  /* Sobre negro un gris tan oscuro como el de los bordes no se ve: el texto
     tenue sube hasta despegarse del fondo sin llegar al del texto normal. */
  --texto-tenue: #7a7a7a;

  --superficie-suave: #242424;
  --superficie-inerte: #1c1c1c;
  --superficie-aviso: #181818;

  --boton-hover: #cfcfcf;
  --foco-halo: rgba(245, 245, 245, 0.3);
  --velo: rgba(0, 0, 0, 0.7);
  --sombra: 0 24px 60px rgba(0, 0, 0, 0.6);
  /* La bola salía de --bg-white, que aquí es casi el mismo negro que la pista:
     el interruptor apagado se veía como una pastilla vacía. */
  --switch-boton: #6f6f6f;
  --sombra-boton: 0 1px 3px rgba(0, 0, 0, 0.6);

  /* Los tonos de estado se apagan sobre fondo oscuro: el fondo se hunde y el
     texto se aclara, manteniendo el mismo verde y el mismo granate. */
  --ok-bg: #17281b;
  --ok-fg: #b7d8bf;
  --error-bg: #2b1614;
  --error-fg: #f2b8b5;
  --error-texto: #f2b8b5;
  --peligro: #b3261e;
  --peligro-hover: #cf4239;
  --peligro-texto: #ffffff;
  --aviso-bg: #241f14;
  --aviso-borde: #d8b45c;

  --flecha-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%239a9a9a' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
}

html {
  font-size: 16px;
  /* Al tocar en móvil el navegador tiñe de azul lo pulsado. */
  -webkit-tap-highlight-color: transparent;
  /* Safari en horizontal agranda por su cuenta el texto de algunos bloques. */
  -webkit-text-size-adjust: 100%;
}

* {
  box-sizing: border-box;
}

body {
  font-family: var(--font-body);
  background-color: var(--bg-light);
  color: var(--text-dark);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  margin: 0;
  padding-top: var(--nav-height);
  padding-bottom: calc(var(--nav-inferior) + env(safe-area-inset-bottom, 0px));
}

/* Guardada en el escritorio del móvil, la aplicación se abre sin barra de
   direcciones (display: standalone del manifiesto). Ahí sobran dos gestos del
   navegador que ninguna app nativa tiene: el tirón hacia abajo que recarga la
   página y el rebote al llegar al final de la lista. */
@media (display-mode: standalone) {
  body {
    overscroll-behavior-y: contain;
  }
}

h1, h2, h3, h4, .heading {
  font-family: var(--font-heading);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0 0 var(--space-2xs);
}

h1 { font-size: clamp(1.85rem, 1.1rem + 3.8vw, 3.6rem); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p {
  font-size: var(--step-0);
  color: var(--text-gray);
}

a {
  text-decoration: none;
  color: inherit;
  transition: color 0.3s ease;
}

.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: var(--space-2xs);
}

.eyebrow::before {
  content: '';
  display: inline-block;
  width: 26px;
  height: 1px;
  background: currentColor;
  vertical-align: middle;
  margin-right: 0.6em;
}

/* ---- Botones -------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.9rem 2.25rem;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  border-radius: 4px;
  /* Bootstrap pinta el botón pulsado y el aro de foco desde sus propias
     variables, y sus reglas pesan más que las de esta hoja: si no se le dan
     nuestros colores, el botón se vuelve azul al pulsarlo. */
  --bs-btn-focus-box-shadow: 0 0 0 3px var(--foco-halo);
}

.btn-primary {
  background-color: var(--text-dark);
  color: var(--bg-white);
  border-color: var(--text-dark);
  --bs-btn-hover-color: var(--bg-white);
  --bs-btn-hover-bg: var(--boton-hover);
  --bs-btn-hover-border-color: var(--boton-hover);
  --bs-btn-active-color: var(--bg-white);
  --bs-btn-active-bg: var(--boton-hover);
  --bs-btn-active-border-color: var(--boton-hover);
}

/* Ojo con :focus a secas: al abrir el diálogo de confirmación el foco cae en
   «Volver» y con él el botón se pintaba de negro, como si fuera la acción
   principal. Con :focus-visible solo se marca al navegar con teclado. */
.btn-primary:hover,
.btn-primary:focus-visible {
  background-color: var(--boton-hover);
  border-color: var(--boton-hover);
  color: var(--bg-white);
}

.btn-outline {
  border-color: var(--text-dark);
  color: var(--text-dark);
  background: transparent;
  --bs-btn-hover-color: var(--bg-white);
  --bs-btn-hover-bg: var(--text-dark);
  --bs-btn-hover-border-color: var(--text-dark);
  --bs-btn-active-color: var(--bg-white);
  --bs-btn-active-bg: var(--text-dark);
  --bs-btn-active-border-color: var(--text-dark);
}

.btn-outline:hover,
.btn-outline:focus-visible {
  background-color: var(--text-dark);
  color: var(--bg-white);
}

/* El granate se queda granate en las dos apariencias, así que su texto no es
   el papel de la página (que sí se invierte) sino su propio color. */
.btn-danger {
  background-color: var(--peligro);
  color: var(--peligro-texto);
  border-color: var(--peligro);
  --bs-btn-hover-color: var(--peligro-texto);
  --bs-btn-hover-bg: var(--peligro-hover);
  --bs-btn-hover-border-color: var(--peligro-hover);
  --bs-btn-active-color: var(--peligro-texto);
  --bs-btn-active-bg: var(--peligro-hover);
  --bs-btn-active-border-color: var(--peligro-hover);
}

.btn-danger:hover,
.btn-danger:focus-visible {
  background-color: var(--peligro-hover);
  border-color: var(--peligro-hover);
  color: var(--peligro-texto);
}

/* Una pantalla táctil no tiene puntero: el :hover se queda pegado desde que se
   toca hasta que se toca otra cosa, y el botón parece estar en otro estado.
   Los de Bootstrap se apagan devolviéndoles el color de reposo. */
@media (hover: none) {
  .btn-primary:hover {
    background-color: var(--text-dark);
    border-color: var(--text-dark);
    --bs-btn-hover-bg: var(--text-dark);
    --bs-btn-hover-border-color: var(--text-dark);
  }

  .btn-outline:hover {
    background-color: transparent;
    color: var(--text-dark);
    --bs-btn-hover-color: var(--text-dark);
    --bs-btn-hover-bg: transparent;
    --bs-btn-hover-border-color: var(--text-dark);
  }

  .btn-danger:hover {
    background-color: var(--peligro);
    border-color: var(--peligro);
    --bs-btn-hover-bg: var(--peligro);
    --bs-btn-hover-border-color: var(--peligro);
  }
}

.btn-link {
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: none;
  border: none;
  padding: 0;
  margin-top: 0.5rem;
  cursor: pointer;
  text-decoration: underline;
}

.btn-link:hover {
  color: var(--text-dark);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-bottom: var(--space-sm);
}

/* El navegador marca el foco con su azul; aquí se marca con el negro de la
   casa. Solo con :focus-visible, o sea al navegar con teclado. */
:focus-visible {
  outline: 2px solid var(--text-dark);
  outline-offset: 2px;
}

input[type="checkbox"] {
  accent-color: var(--text-dark);
}

/* ---- Cabecera --------------------------------------------------------- */

.app-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--nav-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0 clamp(1.15rem, 5vw, 3rem);
  background-color: var(--bg-white);
  border-bottom: 1px solid var(--hairline);
  z-index: 1000;
}

/* La marca de la cabecera es solo el anagrama: el nombre del club no se repite
   al lado porque ya está en el propio dibujo. */
.app-header .logo {
  display: inline-flex;
  align-items: center;
  color: var(--text-dark);
}

/* El anagrama se pinta con currentColor, así que sigue al color de la cabecera
   y no hace falta una versión clara aparte para el modo oscuro. */
.logo-marca {
  width: 34px;
  height: 34px;
  flex: none;
}

.app-header .nav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.app-header .nav-links a {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dark);
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
}

.app-header .nav-links a:hover,
.app-header .nav-links a.active {
  border-bottom-color: var(--text-dark);
}

/* Los iconos son solo para la barra de pestañas de móvil. */
.nav-icon {
  display: none;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-user-corto {
  display: none;
}

.app-header .nav-links .nav-user {
  /* El correo puede ser larguísimo: se recorta antes de empujar la cabecera. */
  max-width: min(34vw, 260px);
}

.nav-user-largo {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Secciones oscuras ------------------------------------------------ */

.section-dark {
  background-color: var(--surface-dark);
  color: var(--bg-white);
}

.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4 {
  color: var(--bg-white);
}

.section-dark p {
  color: var(--texto-invertido);
}

.section-dark .eyebrow {
  color: var(--accent);
}

/* ---- Layout general ---------------------------------------------------- */

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 clamp(1.15rem, 5vw, 3rem);
}

main {
  min-height: calc(100vh - var(--nav-height));
}

/* En móvil la barra del navegador entra y sale, y 100vh cuenta siempre la
   pantalla entera: con dvh la página no arrastra un hueco de más. */
@supports (height: 100dvh) {
  main {
    min-height: calc(100dvh - var(--nav-height));
  }
}

/* El relleno vertical del contenido va aquí y no en el atributo style del
   layout, para poder ajustarlo en móvil. */
main.container {
  padding-block: var(--space-md) var(--space-lg);
}

/* ---- Mensajes flash ------------------------------------------------- */

.flash {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--step-sm);
  padding: 0.75rem 1rem;
  border-radius: 4px;
  margin-bottom: var(--space-sm);
}

.flash-ok {
  background: var(--ok-bg);
  color: var(--ok-fg);
}

.flash-error {
  background: var(--error-bg);
  color: var(--error-fg);
}

/* ---- Diálogo de confirmación ------------------------------------------- */
/* Sustituye al aviso del navegador. El nombre no puede ser .modal: esa clase
   ya es de Bootstrap y llega con display:none. */

.confirmar {
  width: min(420px, calc(100vw - 2rem));
  padding: 0;
  color: var(--text-dark);
  background: var(--bg-white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--sombra);
}

.confirmar::backdrop {
  background: var(--velo);
}

@media (prefers-reduced-motion: no-preference) {
  .confirmar[open] {
    animation: confirmar-entra 0.2s var(--ease);
  }
}

@keyframes confirmar-entra {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

.confirmar-caja {
  padding: var(--space-sm);
}

.confirmar-titulo {
  font-size: var(--step-1);
}

.confirmar-texto {
  font-size: var(--step-sm);
  margin: 0 0 var(--space-xs);
}

.confirmar-acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2xs);
}

/* ---- Calendario semanal ------------------------------------------------ */

.week-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  margin: var(--space-sm) 0;
  flex-wrap: wrap;
}

.week-nav .btn-sm,
.btn-sm {
  padding: 0.5rem 1.1rem;
  font-size: 0.8rem;
}

.week-nav-label {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dark);
}

.week-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-sm);
}

.day-card {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--space-xs);
}

.day-card-heading {
  font-size: var(--step-1);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: var(--space-2xs);
  margin-bottom: var(--space-xs);
}

.day-card-date {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--step-xs);
  text-transform: none;
  letter-spacing: 0;
  color: var(--accent-ink);
}

.day-card-empty {
  color: var(--texto-tenue);
  font-size: var(--step-sm);
}

.class-row {
  padding: var(--space-2xs) 0;
  border-bottom: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.class-row:last-child {
  border-bottom: none;
}

.class-row-cancelada {
  opacity: 0.55;
}

.class-row-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.class-row-hora {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--step-sm);
}

.class-row-nombre {
  font-weight: 600;
  font-size: var(--step-sm);
}

.class-row-profesor,
.class-row-plazas {
  font-size: var(--step-xs);
  color: var(--accent-ink);
}

.class-row-accion {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.badge {
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.3rem 0.7rem;
  border-radius: 4px;
}

.badge-ok {
  background: var(--ok-bg);
  color: var(--ok-fg);
}

.badge-wait {
  background: var(--superficie-suave);
  color: var(--text-gray);
}

.badge-muted {
  background: var(--superficie-suave);
  color: var(--texto-tenue);
}

/* Distintivo pequeño en línea con el nombre de la clase */
.tag {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-ink);
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 0.05rem 0.35rem;
  vertical-align: middle;
  margin-left: 0.35rem;
}

/* Acciones de profesor/administrador sobre una clase concreta */
.class-row-gestor {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  border-top: 1px dashed var(--hairline);
  padding-top: 0.4rem;
}

.class-row-gestor .btn-link {
  margin-top: 0;
}

/* ---- Paneles plegables y formularios de gestión ------------------------- */

.panel {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.panel-summary {
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  cursor: pointer;
}

.panel-summary:hover {
  color: var(--text-dark);
}

.panel[open] > .panel-summary {
  color: var(--text-dark);
  margin-bottom: var(--space-xs);
}

/* Dentro de una tarjeta de día el panel no necesita marco propio */
.panel-inline {
  border: none;
  border-radius: 0;
  padding: 0;
  margin-bottom: 0;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-xs);
  align-items: end;
}

.form-grid .field {
  margin-bottom: 0;
}

/* Aquí había un padding reducido para input y select. Sobre los input no podía
   nada (los selectores de «.field input[type=...]» pesan lo mismo y van
   después), así que solo encogía los select y quedaban más bajos que los campos
   de al lado. Todos usan ya el tamaño de «.field». */

/* En la tarjeta de un día no hay ancho para varias columnas */
.form-grid-compacto {
  grid-template-columns: 1fr;
  gap: var(--space-2xs);
}

.form-grid-acciones {
  display: flex;
  gap: var(--space-2xs);
}

/* El botón cierra la fila de campos de la rejilla (Plantilla, Clases), así que
   comparte su alto: .btn-sm solo fija relleno y letra y se quedaba trece
   píxeles por debajo. Sube el alto, no el tamaño de letra: sigue siendo un
   botón pequeño. */
.form-grid-acciones .btn {
  min-height: var(--control-alto);
}

.form-grid .field-check {
  align-self: center;
}

.form-grid .field-check input[type="checkbox"] {
  width: auto;
}

.form-eliminar {
  margin-top: var(--space-2xs);
}

/* ---- Formularios (login, registro) -------------------------------------- */

.auth-form {
  max-width: 420px;
}

.field {
  margin-bottom: var(--space-xs);
}

.field label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: 0.4rem;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="tel"],
.field input[type="number"],
.field input[type="file"],
.field input[type="date"],
.field input[type="time"],
.field select {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--step-0);
  color: var(--text-dark);
  background: var(--bg-white);
  border: 1px solid var(--accent-soft);
  border-radius: 4px;
  padding: 0.75rem 0.9rem;
  /* Cada control mide lo que el navegador quiera: el select ignora la altura de
     línea y se queda corto, y el reloj de los campos de hora estira el suyo. Con
     una altura común todos coinciden, que es lo que se ve al ponerlos en fila.
     El token lo usan también los botones que cierran esas filas. */
  line-height: 1.5;
  height: var(--control-alto);
  transition: border-color 0.2s ease;
}

/* El de archivo lleva dentro el botón del navegador y necesita su propio alto. */
.field input[type="file"] {
  height: auto;
}

/* Sin esto iOS dibuja fecha y hora con su propio ancho y su propio alto, y no
   pegan con el resto de campos. */
.field input[type="date"],
.field input[type="time"] {
  -webkit-appearance: none;
  appearance: none;
}

/* Y por lo mismo el desplegable: con la pinta del sistema cada navegador le da
   el alto que quiere y la fila deja de cuadrar justo donde más se usa la app,
   que es Safari y iOS. Se le quita y se le dibuja flecha propia.
   Ojo al tocar estas reglas: quien venga detrás tiene que pintar el fondo con
   background-color, nunca con el atajo background, o borra la flecha. */
.field select,
.admin-filtros .field select,
.admin-table select {
  -webkit-appearance: none;
  appearance: none;
  background-image: var(--flecha-select);
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 12px 8px;
}

/* Hueco para que la flecha no se monte encima del texto de la opción */
.field select {
  padding-right: 2.25rem;
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--text-dark);
}

.field input:disabled {
  background: var(--superficie-inerte);
  color: var(--accent-ink);
  cursor: not-allowed;
}

.field-hint {
  display: block;
  font-size: var(--step-xs);
  color: var(--accent-ink);
  margin-top: 0.35rem;
}

/* Campo verificado: marca ✓ dentro del propio input */
.field-verified {
  position: relative;
}

.field-verified input {
  padding-right: 2.5rem;
}

.field-verified::after {
  content: '✓';
  position: absolute;
  right: 0.9rem;
  bottom: 0.75rem;
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--ok-fg);
}

.field-check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--step-sm);
  color: var(--text-gray);
}

.field-check input {
  width: auto;
}

/* ---- Interruptor (ajustes) ---------------------------------------------- */
/* Una casilla normal disfrazada de interruptor: el <input> sigue ahí, solo que
   tapado por la pista, así que el teclado y los lectores de pantalla lo
   manejan como lo que es. */

.switch {
  /* El <input> va encima de la pista, no suelto por la página */
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
}

/* Gana a la regla de .field label, que pone las etiquetas en versalitas grises.
   El display hay que repetirlo aquí: «.field label» pesa más que «.switch» a
   secas, así que dentro de un .field la etiqueta se quedaba en display:block y
   la pista, que es un <span>, volvía a ser una caja en línea. Un elemento en
   línea no hace caso al ancho ni al alto, de modo que la pista se encogía a su
   borde y la bola se salía por encima del texto. */
.field label.switch {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--step-0);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-dark);
  margin-bottom: 0;
}

.switch input[type="checkbox"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 44px;
  height: 26px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.switch-pista {
  position: relative;
  /* Es un <span>: sin esto depende de que el padre sea flex para dejar de ser
     una caja en línea y poder tener ancho y alto. */
  display: block;
  flex: none;
  width: 44px;
  height: 26px;
  border-radius: 13px;
  background: var(--superficie-suave);
  border: 1px solid var(--accent-soft);
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.switch-pista::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--switch-boton);
  box-shadow: var(--sombra-boton);
  transition: transform 0.2s var(--ease), background-color 0.2s ease;
}

.switch input:checked ~ .switch-pista {
  background: var(--text-dark);
  border-color: var(--text-dark);
}

/* Encendido la pista es el color del texto, así que la bola pasa a ser el
   papel: en claro negra con bola blanca y en oscuro al revés. */
.switch input:checked ~ .switch-pista::after {
  transform: translateX(18px);
  background: var(--bg-white);
}

.switch input:focus-visible ~ .switch-pista {
  outline: 2px solid var(--text-dark);
  outline-offset: 2px;
}

.field-error {
  display: block;
  color: var(--error-texto);
  font-size: var(--step-xs);
  margin-top: 0.35rem;
}

.validation-summary-errors ul {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-sm);
}

.validation-summary-errors li {
  color: var(--error-texto);
  font-size: var(--step-sm);
  font-weight: 600;
}

.auth-form .btn {
  width: 100%;
  margin-top: var(--space-2xs);
}

.auth-links {
  margin-top: var(--space-sm);
  font-size: var(--step-sm);
}

/* ---- Mi cuenta (área Identity) ----------------------------------------- */

.account-layout {
  display: grid;
  grid-template-columns: minmax(170px, 210px) minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--hairline);
}

@media (max-width: 720px) {
  .account-layout {
    grid-template-columns: 1fr;
    gap: var(--space-sm);
  }

  /* Sin esto la celda crece hasta caber su contenido y la tira de pestañas
     de la cuenta empuja la página a lo ancho en vez de desplazarse sola. */
  .account-layout > * {
    min-width: 0;
  }
}

.account-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 1px solid var(--hairline);
}

.account-nav a {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  padding: 0.7rem 0 0.7rem 1rem;
  margin-left: -1px;
  border-left: 2px solid transparent;
}

.account-nav a:hover {
  color: var(--text-dark);
}

.account-nav a.active {
  color: var(--text-dark);
  border-left-color: var(--text-dark);
}

/* Salir es una opción más de la cuenta, pero va aparte del resto */
.account-nav-salir {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: none;
  border: none;
  border-left: 2px solid transparent;
  border-top: 1px solid var(--hairline);
  padding: 0.7rem 0 0.7rem 1rem;
  margin-left: -1px;
  margin-top: 0.4rem;
  cursor: pointer;
}

.account-nav-salir:hover {
  color: var(--text-dark);
}

.account-panel {
  max-width: 460px;
}

.account-panel > h3 {
  margin-bottom: var(--space-xs);
}

.account-panel h4 {
  margin-top: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.account-panel .btn {
  width: 100%;
}

/* Botones que conviven en fila no ocupan el ancho completo */
.account-panel .btn-row .btn {
  width: auto;
}

/* ---- Foto de perfil ----------------------------------------------------- */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--superficie-suave);
  border: 1px solid var(--hairline);
}

.avatar-placeholder {
  font-family: var(--font-heading);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent-ink);
}

.avatar-lg {
  width: 96px;
  height: 96px;
}

.avatar-lg.avatar-placeholder {
  font-size: 1.6rem;
}

.nav-user {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

.avatar-field {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-xs);
}

.avatar-field .field {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}

/* ---- Avisos (sustituyen a los .alert de Bootstrap) --------------------- */

.notice {
  background: var(--superficie-aviso);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--text-dark);
  border-radius: 4px;
  padding: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.notice p {
  margin: 0 0 0.5rem;
  font-size: var(--step-sm);
}

.notice p:last-child {
  margin-bottom: 0;
}

.notice strong {
  color: var(--text-dark);
  font-weight: 600;
}

.notice a {
  text-decoration: underline;
}

/* Identificadores largos: se parten antes que desbordar la pantalla. */
.notice code {
  font-size: var(--step-xs);
  word-break: break-all;
}

.notice-warn {
  background: var(--aviso-bg);
  border-left-color: var(--aviso-borde);
}

.notice-danger {
  background: var(--error-bg);
  border-left-color: var(--error-fg);
}

/* ---- Tabla de accesos externos ----------------------------------------- */

.account-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--space-sm);
}

.account-table td {
  border-bottom: 1px solid var(--hairline);
  padding: var(--space-2xs) 0;
  font-size: var(--step-sm);
}

.account-table td:last-child {
  text-align: right;
}

/* ---- Listado de usuarios (administración) ------------------------------- */

.admin-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

/* Reparten el ancho a partes iguales; con min-width cada campo se quedaba del
   ancho de su contenido y los tres salían distintos. */
.admin-filtros .field {
  margin-bottom: 0;
  flex: 1 1 190px;
}

/* Aquí estaba el escalón de la pantalla de usuarios: se reducían el padding y
   la letra pero no la altura, que seguía saliendo de la fórmula de «.field» y
   del em de la letra nueva. El campo pedía 41px y medía 49. Es el mismo fallo
   que se cuenta más arriba, en «.form-grid».
   Ahora el alto es el token y el padding solo horizontal: con el alto fijo el
   vertical no pinta nada y era justo lo que descuadraba la cuenta. */
.admin-filtros .field input,
.admin-filtros .field select {
  height: var(--control-alto-sm);
  padding: 0 0.7rem;
  font-size: var(--step-sm);
}

.admin-filtros .field select {
  padding-right: 2.1rem;
}

.admin-filtros-acciones {
  display: flex;
  gap: var(--space-2xs);
}

/* Filtrar y Limpiar cierran la fila de campos: miden lo que ellos. Con
   min-height y no height, porque el botón es inline-flex y así el alto es un
   suelo que nunca puede recortarle el texto. */
.admin-filtros-acciones .btn {
  min-height: var(--control-alto-sm);
}

.admin-total,
.admin-empty {
  font-size: var(--step-sm);
  color: var(--text-gray);
  margin-bottom: var(--space-2xs);
}

/* La tabla no cabe en móvil: se desplaza dentro de su propia caja */
.table-scroll {
  overflow-x: auto;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-sm);
}

.admin-table th {
  text-align: left;
  font-family: var(--font-body);
  font-size: var(--step-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  white-space: nowrap;
  border-bottom: 1px solid var(--hairline);
  padding: 0 var(--space-2xs) var(--space-2xs) 0;
}

.admin-table td {
  vertical-align: middle;
  border-bottom: 1px solid var(--hairline);
  padding: var(--space-2xs) var(--space-2xs) var(--space-2xs) 0;
}

.admin-table td:last-child,
.admin-table th:last-child {
  padding-right: 0;
}

.admin-table select {
  font-family: var(--font-body);
  font-size: var(--step-sm);
  color: var(--text-dark);
  background-color: var(--bg-white);
  border: 1px solid var(--accent-soft);
  border-radius: 4px;
  /* El mismo alto que el botón Guardar de su fila */
  height: var(--control-alto-sm);
  line-height: 1.5;
  vertical-align: middle;
  padding: 0 2rem 0 0.55rem;
  transition: border-color 0.2s ease;
}

.admin-table select:focus {
  outline: none;
  border-color: var(--text-dark);
}

.admin-table select:disabled {
  background-color: var(--superficie-inerte);
  color: var(--accent-ink);
  cursor: not-allowed;
}

.admin-table-accion {
  text-align: right;
  white-space: nowrap;
}

.admin-table-accion .btn {
  min-height: var(--control-alto-sm);
}

.usuario-nombre {
  display: block;
  font-weight: 600;
  color: var(--text-dark);
}

.usuario-email,
.usuario-nota {
  font-size: var(--step-xs);
  color: var(--text-gray);
}

.usuario-email {
  display: block;
}

/* La nota del rol («Es tu cuenta», «También: …», «Sin rol asignado») iba debajo
   del select, y como la celda centra su contenido esa columna pasaba a medir
   dos líneas: el select del rol se subía y dejaba de cuadrar con el del
   cinturón y con Guardar, por mucho que los tres midan ya lo mismo. Puesta al
   lado, la celda vuelve a ser de una línea y la fila se alinea sola.
   En móvil la celda es flex y la nota vuelve a bajar (ver el bloque de móvil). */
.usuario-nota {
  display: inline-block;
  vertical-align: middle;
  margin-left: var(--space-2xs);
}

/* =========================================================================
   Móvil
   La app se usa sobre todo desde el teléfono: por debajo de 720px la
   navegación baja a una barra de pestañas al alcance del pulgar, las tablas
   se convierten en tarjetas y todo lo que se toca crece hasta un tamaño
   cómodo. El corte son 720px, el ancho al que la cabecera de escritorio deja
   de caber en una línea.
   ========================================================================= */

@media (max-width: 720px) {
  :root {
    --nav-height: 56px;

    /* Un objetivo de toque por debajo de 44px se falla constantemente: el
       tamaño compacto sube hasta ahí y con él todo lo que usa el token, campos
       y botones a la vez, sin repetir la medida control a control. */
    --control-alto-sm: 2.75rem;
  }

  /* Solo con la sesión iniciada hay barra abajo, y solo entonces el contenido
     necesita dejarle sitio. Sin sesión (entrar, registro) la variable sigue a 0.
     Con la barra de pestañas abajo la cabecera no aporta nada: se repliega
     (--nav-height a 0) y su alto pasa al contenido. */
  .con-nav-inferior {
    --nav-inferior: 62px;
    --nav-height: 0px;
  }

  /* ---- Cabecera ---------------------------------------------------------- */

  .app-header {
    gap: 1rem;
    padding: 0 1.15rem;
  }

  .logo-marca {
    width: 30px;
    height: 30px;
  }

  /* La barra de pestañas es hija de la cabecera, así que aquí no vale un
     display:none: se le quita el cuerpo y se deja solo de contenedor. */
  .con-nav-inferior .app-header {
    padding: 0;
    background-color: transparent;
    border-bottom: none;
  }

  .con-nav-inferior .app-header .logo {
    display: none;
  }

  /* ---- Barra de pestañas ------------------------------------------------- */
  /* Con la sesión iniciada la navegación se despega de la cabecera y se ancla
     abajo. El hueco de env(safe-area-inset-bottom) es la franja del gesto de
     inicio de los móviles sin botón. */

  .nav-app {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    height: calc(var(--nav-inferior) + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    gap: 0;
    background-color: var(--bg-white);
    border-top: 1px solid var(--hairline);
    z-index: 1000;
  }

  .app-header .nav-app a {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    min-width: 0;
    max-width: none;
    padding: 0.3rem 0.15rem;
    /* En caja alta «Entrenamiento» no cabe en una pestaña de cuatro. */
    text-transform: none;
    font-size: 0.66rem;
    letter-spacing: 0.01em;
    color: var(--accent-ink);
    border-bottom: none;
    text-align: center;
  }

  .app-header .nav-app a > span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .app-header .nav-app a:hover,
  .app-header .nav-app a.active {
    color: var(--text-dark);
    border-bottom: none;
  }

  .nav-app .nav-icon {
    display: block;
  }

  .nav-app .nav-user {
    gap: 0.15rem;
  }

  .nav-app .nav-user-largo {
    display: none;
  }

  .nav-app .nav-user-corto {
    display: block;
  }

  .nav-app .avatar {
    width: 22px;
    height: 22px;
  }

  .nav-app .avatar-placeholder {
    font-size: 0.52rem;
  }

  /* ---- Ritmo general ----------------------------------------------------- */

  main.container {
    padding-block: var(--space-sm) var(--space-md);
  }

  .notice,
  .panel {
    padding: 0.9rem 1rem;
  }

  /* Sin tocar el display: cualquier otro valor le quita el triángulo al summary. */
  .panel-summary {
    padding: 0.3rem 0;
  }

  /* ---- Cosas que se tocan ------------------------------------------------ */
  /* Un objetivo de toque por debajo de 44px se falla constantemente. */

  .btn {
    min-height: 44px;
    padding: 0.75rem 1.35rem;
    font-size: 0.95rem;
  }

  .week-nav .btn-sm,
  .btn-sm {
    min-height: 40px;
    padding: 0.5rem 0.9rem;
    font-size: 0.78rem;
  }

  .btn-link {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    padding: 0.3rem 0;
  }

  /* Safari amplía la página al enfocar un campo de menos de 16px. */
  .field input:not([type="checkbox"]),
  .field select,
  .form-grid .field input,
  .form-grid .field select,
  .admin-filtros .field input,
  .admin-filtros .field select,
  .admin-table select {
    min-height: 44px;
    font-size: 16px;
  }

  /* ---- Rejilla de formulario --------------------------------------------- */
  /* Dos columnas: las horas caben de sobra en media, el resto no. */

  .form-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2xs);
  }

  .form-grid .field-ancho,
  .form-grid .field-check,
  .form-grid-acciones {
    grid-column: 1 / -1;
  }

  .form-grid-compacto {
    grid-template-columns: 1fr;
  }

  /* En la ficha ya no comparte fila con ningún campo: manda el objetivo de
     toque, no el alto de la rejilla. */
  .form-grid-acciones .btn {
    width: 100%;
    min-height: var(--control-alto-sm);
  }

  /* ---- Calendario y horario ---------------------------------------------- */

  .week-nav {
    flex-wrap: nowrap;
    gap: 0.5rem;
    margin: var(--space-xs) 0;
  }

  .week-nav-btn {
    flex: none;
    padding: 0.5rem 0.95rem;
    font-size: 1rem;
  }

  /* De los botones de semana solo queda la flecha; el rango de fechas manda. */
  .week-nav-texto {
    display: none;
  }

  .week-nav-label {
    flex: 1;
    text-align: center;
    font-size: 0.92rem;
    white-space: nowrap;
  }

  .week-grid {
    grid-template-columns: 1fr;
    gap: var(--space-xs);
  }

  .day-card {
    padding: 0.9rem 1rem;
  }

  .class-row {
    gap: 0.6rem;
    padding: 0.7rem 0;
  }

  /* El botón de la clase ocupa la fila entera junto a su distintivo. */
  .class-row-accion {
    flex-wrap: wrap;
  }

  .class-row-accion form {
    flex: 1 1 8rem;
  }

  .class-row-accion .btn {
    width: 100%;
  }

  .class-row-gestor {
    gap: 1.25rem;
    padding-top: 0.2rem;
  }

  /* ---- Mi cuenta ---------------------------------------------------------- */

  .account-layout {
    margin-top: var(--space-xs);
    padding-top: var(--space-xs);
  }

  /* La columna de secciones pasa a una tira de pestañas que se desplaza. */
  .account-nav {
    display: flex;
    gap: 0.15rem;
    overflow-x: auto;
    border-left: none;
    border-bottom: 1px solid var(--hairline);
    scrollbar-width: none;
  }

  .account-nav::-webkit-scrollbar {
    display: none;
  }

  .account-nav > li {
    flex: 0 0 auto;
  }

  .account-nav a,
  .account-nav-salir {
    width: auto;
    margin: 0;
    padding: 0.7rem 0.75rem;
    white-space: nowrap;
    border-top: none;
    border-left: none;
    border-bottom: 2px solid transparent;
  }

  .account-nav a.active {
    border-bottom-color: var(--text-dark);
  }

  .account-panel {
    max-width: none;
  }

  /* La foto y el selector de archivo no caben uno al lado del otro. */
  .avatar-field {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2xs);
  }

  .avatar-field .field {
    width: 100%;
  }

  /* ---- Listado de usuarios ------------------------------------------------ */

  .admin-filtros {
    gap: var(--space-2xs);
  }

  .admin-filtros .field,
  .admin-filtros-acciones {
    flex: 1 1 100%;
  }

  .admin-filtros .field input,
  .admin-filtros .field select {
    width: 100%;
    min-width: 0;
  }

  .admin-filtros-acciones .btn {
    flex: 1;
  }

  /* Seis columnas no caben en un teléfono: cada usuario pasa a ser una ficha
     y el encabezado de cada dato lo pone el propio data-label. */
  .table-scroll {
    overflow-x: visible;
  }

  .admin-table,
  .admin-table tbody,
  .admin-table tr,
  .admin-table td {
    display: block;
    width: 100%;
  }

  .admin-table thead {
    display: none;
  }

  .admin-table tr {
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    padding: var(--space-xs);
    margin-bottom: var(--space-xs);
  }

  .admin-table td {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2xs);
    border-bottom: none;
    padding: 0.3rem 0;
  }

  .admin-table td[data-label]::before {
    content: attr(data-label);
    flex: none;
    font-family: var(--font-body);
    font-size: var(--step-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-ink);
  }

  /* La primera celda hace de titular de la ficha. */
  .admin-table td:first-child {
    display: block;
    border-bottom: 1px solid var(--hairline);
    padding-bottom: var(--space-2xs);
    margin-bottom: var(--space-2xs);
  }

  .admin-table select {
    max-width: 62%;
  }

  .admin-table .usuario-nota {
    flex: 1 1 100%;
    text-align: right;
    margin-top: 0;
    /* En escritorio va al lado del select y lleva margen; aquí, no. */
    margin-left: 0;
  }

  .admin-table-accion {
    padding-top: var(--space-2xs);
  }

  .admin-table-accion .btn {
    width: 100%;
  }

  /* ---- Diálogo de confirmación -------------------------------------------- */
  /* En el teléfono se comporta como una hoja que sube desde abajo. */

  .confirmar {
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    border: none;
    border-top: 1px solid var(--hairline);
    border-radius: var(--radius) var(--radius) 0 0;
  }

  .confirmar-caja {
    padding: var(--space-sm) var(--space-xs) calc(var(--space-xs) + env(safe-area-inset-bottom, 0px));
  }

  .confirmar-acciones .btn {
    flex: 1 1 auto;
  }

  @media (prefers-reduced-motion: no-preference) {
    .confirmar[open] {
      animation: confirmar-sube 0.24s var(--ease);
    }
  }
}

@keyframes confirmar-sube {
  from {
    transform: translateY(100%);
  }
}

/* Entre el móvil y el escritorio holgado los dos botones de semana y el rango
   de fechas no caben a tamaño completo, y la fila se partía en dos. */
@media (min-width: 721px) and (max-width: 960px) {
  .week-nav-btn {
    padding: 0.65rem 1.4rem;
    font-size: 0.85rem;
  }
}
