:root {
  --color-bg: #f4f6f5;
  --color-surface: #ffffff;
  --color-border: #e2e6e4;
  --color-text: #1e2622;
  --color-text-muted: #6b756f;
  --color-primary: #2f8f6e;
  --color-primary-dark: #24704f;
  --color-danger: #c0392b;
  --color-danger-bg: #fdecea;
  --color-success-bg: #e9f7f0;
  --radius: 12px;
  --gap: 16px;
  /* Expuesto como custom property para poder leerlo desde JS (clamp del
     drag del water-fab, ver wireWaterFab) — env() no es legible por getComputedStyle
     salvo que esté asignado a una property así. */
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  font-size: 16px;
}

* { box-sizing: border-box; }

/* Safety net mobile: sin esto, un <img> sin clase (o un navegador que no
   aplicó bien el CSS específico) puede renderizarse a su tamaño nativo —
   "la foto de perfil gigante" es exactamente ese síntoma. */
img { max-width: 100%; height: auto; display: block; }

/* iOS/Android le ponen su propio "look" nativo (gris, con relieve) a
   button/select/input salvo que se lo saques a mano — si no, la botonera
   custom (choice-btn, type-btn, quality-btn, etc.) se ve rota en el
   celular aunque en la compu esté perfecta. Los date/datetime-local/file
   quedan afuera a propósito: ahí el look nativo es el que da el selector
   lindo del sistema operativo. */
button,
select,
input:not([type="date"]):not([type="datetime-local"]):not([type="file"]):not([type="checkbox"]) {
  font-family: inherit;
  -webkit-appearance: none;
  appearance: none;
}
button { cursor: pointer; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

#app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh; /* alto real de pantalla en mobile, sin contar la barra de direcciones */
  display: flex;
  flex-direction: column;
  /* espacio para el tab-bar fijo + el "home indicator" de iPhones sin botón físico */
  padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
}

h1, h2, h3 { margin: 0 0 4px; line-height: 1.25; }
p { margin: 0; }

/* ---------- Header ---------- */
.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px var(--gap) 8px;
}
.app-header .brand { display: flex; align-items: center; gap: 10px; }
.app-header img { width: 32px; height: 32px; border-radius: 8px; object-fit: cover; }
.app-header img.logo-mono { border-radius: 0; object-fit: contain; }
.app-header .logout-btn {
  background: none; border: none; color: var(--color-text-muted);
  font-size: 0.85rem; padding: 8px; cursor: pointer;
}
/* Desplegable Persona/Profesor, entre el logo y "Salir" — ancho propio en vez del 100% que usan los <select> del resto de la app. */
.app-header #profile-switcher {
  width: auto;
  flex: 1;
  margin: 0 10px;
  padding-top: 6px;
  padding-bottom: 6px;
  font-size: 0.78rem;
}

/* ---------- Auth (login/registro) ---------- */
.auth-screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--gap);
  background: linear-gradient(180deg, #eaf6ef 0%, var(--color-bg) 60%);
}
.auth-card {
  border: none;
  border-radius: 24px;
  box-shadow: 0 14px 40px rgba(36, 112, 79, 0.14);
  padding: 32px 26px;
  margin: 0;
}
.auth-card h2 { text-align: center; font-size: 1.15rem; margin-bottom: 16px; }
.auth-card input, .auth-card select { border-radius: 12px; }
.auth-card .btn { border-radius: 12px; }
.auth-brand { text-align: center; margin-bottom: 22px; }
.auth-logo {
  width: 104px;
  height: 104px;
  border-radius: 26px;
  object-fit: cover;
  margin: 0 auto; /* el reset global "img{display:block}" rompe el centrado por text-align, esto lo repone */
}
.auth-subtitle {
  color: var(--color-text-muted);
  font-style: italic;
  font-size: 0.78rem;
  line-height: 1.4;
  margin-top: 16px;
  padding: 0 6px;
  text-align: center;
}
.auth-subtitle strong { display: block; font-style: normal; font-weight: 700; margin-top: 2px; }

/* ---------- Cards ---------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--gap);
  margin: 0 var(--gap) var(--gap);
}
.card + .card { margin-top: 0; }
.card h2 { font-size: 1rem; }
.card h3 { font-size: 0.9rem; color: var(--color-text-muted); font-weight: 600; }

/* Títulos que van sueltos fuera de una .card (ej: "Cumplimientos diarios" y
   sus categorías) — sin esto quedan pegados a los bordes de la pantalla,
   las .card sí tienen ese aire por su margin lateral. */
.section-heading { padding: 0 var(--gap); }

/* ---------- Forms ---------- */
form { display: flex; flex-direction: column; gap: 12px; }
label { font-size: 0.85rem; font-weight: 600; color: var(--color-text-muted); display: block; margin-bottom: 4px; }
input, select, textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font-size: 1rem;
  background: var(--color-surface);
  color: var(--color-text);
  font-family: inherit;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--color-primary); outline-offset: 1px; }
textarea { resize: vertical; min-height: 60px; }

/* Flechita manual: el -webkit-appearance:none del reset le saca la nativa a los <select>. */
select {
  padding-right: 34px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--color-text-muted) 50%),
    linear-gradient(135deg, var(--color-text-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) center, calc(100% - 13px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.field-row { display: flex; flex-wrap: wrap; gap: 12px; }
.field-row > div { flex: 1 1 130px; min-width: 0; } /* min-width:0 = un input largo no fuerza el ancho del flex item */

button {
  font-family: inherit;
  cursor: pointer;
}
.btn {
  display: block;
  width: 100%;
  padding: 13px;
  border: none;
  border-radius: 8px;
  background: var(--color-primary);
  color: #fff;
  font-size: 1rem;
  font-weight: 600;
}
.btn:active { background: var(--color-primary-dark); }
.btn:disabled { opacity: 0.6; }
.btn-secondary { background: none; color: var(--color-primary); border: 1px solid var(--color-primary); }
.btn-link {
  background: none; border: none; color: var(--color-primary);
  font-size: 0.9rem; padding: 4px; text-decoration: underline;
}

.form-error {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 0.88rem;
}

/* ---------- Dashboard ---------- */
.imc-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  background: var(--color-success-bg);
  color: var(--color-primary-dark);
}

/* ---------- Avatar / foto de perfil ---------- */
.body-row { display: flex; align-items: center; gap: 14px; margin-top: 8px; }
.avatar-btn {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  padding: 0;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
}
.avatar-btn img { width: 100%; height: 100%; object-fit: cover; }
.avatar-placeholder { font-size: 1.7rem; }

.avatar-upload-wrap { display: flex; justify-content: center; margin-bottom: 10px; }
.avatar-large {
  width: 100px;
  height: 100px;
  min-width: 100px; /* nunca se achica ni se agranda, sea cual sea la pantalla o la imagen que subiste */
  min-height: 100px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-bg);
  border: 2px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.8rem;
  flex-shrink: 0;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 12px;
}
.stat-tile {
  background: var(--color-bg);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.stat-tile .stat-emoji { font-size: 1.6rem; line-height: 1; }
.stat-tile .stat-tile-info { display: flex; flex-direction: column; }
.stat-tile .value { font-size: 1.2rem; font-weight: 700; }
.stat-tile .label { font-size: 0.75rem; color: var(--color-text-muted); }

/* "Planificado para hoy" (Inicio, dentro de la tarjeta "Hoy"): mismas fichas
   que la Planificación semanal (ver planChipHtml), pero de solo lectura acá
   — sin drag&drop, así que se resetea el cursor/touch-action de arrastre. */
.today-plan-caption { margin: 12px 0 6px; font-size: 0.75rem; color: var(--color-text-muted); }
.today-plan-list { display: flex; flex-wrap: wrap; gap: 8px; }
.today-plan-list .plan-chip { cursor: default; touch-action: auto; }

.checklist { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.checklist li { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; }
.check-dot {
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; flex-shrink: 0;
  background: var(--color-border); color: transparent;
}
.check-dot.done { background: var(--color-primary); color: #fff; }

.compliance-bar {
  height: 10px;
  border-radius: 999px;
  background: var(--color-border);
  overflow: hidden;
  margin-top: 10px;
}
.compliance-bar > div { height: 100%; background: var(--color-primary); }

.motivational { margin-top: 10px; font-size: 0.92rem; color: var(--color-text-muted); }

/* Inicio (dashboard): todo el texto no-seleccionable — con selección de texto
   habilitada, un long-press para arrastrar "Objetivos activos" (ver
   wireGoalMiniGridDragDrop) puede disparar el menú/selección nativa del
   navegador en vez del drag. */
.dashboard-view { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }

/* Calendario: todo el texto no-seleccionable — es una vista de solo lectura
   (heatmap + detalle del día), no hay nada para editar ahí. */
.calendar-view { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }

/* ---------- Planificación semanal (drag&drop de objetivos a un día) ---------- */
.plan-dropzone {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 40px; /* así una dropzone vacía sigue siendo un blanco fácil para soltar */
  padding: 6px;
  border-radius: var(--radius);
  border: 1px dashed transparent;
  transition: background 0.1s ease, border-color 0.1s ease;
}
.plan-dropzone.drag-over { background: var(--color-success-bg); border-color: var(--color-primary); }
.plan-chip {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  /* Reordenamiento por long-press+arrastre (ver wirePlanningDragDrop): sin
     esto, agarrar la ficha en mobile puede quedar "peleando" con el scroll
     nativo de la página. */
  touch-action: none;
  cursor: grab;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
/* La ficha original mientras se arrastra: se queda en su lugar (sin sacarla
   del flujo — eso corriría todo lo de abajo, ver wirePlanningDragDrop), solo
   atenuada. El "ghost" es el clon que realmente sigue al puntero. */
.plan-chip.dragging-source { opacity: 0.35; }
.plan-chip-ghost {
  position: fixed;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  z-index: 999;
}
.plan-chip-count {
  background: var(--color-primary); color: #fff;
  font-size: 0.68rem; font-weight: 700;
  border-radius: 999px; padding: 1px 6px;
}
.plan-chip-mark { font-size: 0.85rem; }
.plan-chip-mark.done { color: var(--color-primary-dark); }
.plan-chip-mark.missed { color: var(--color-danger); }
.plan-week { display: flex; flex-direction: column; }
.plan-day { padding: 8px 0; border-bottom: 1px solid var(--color-border); }
.plan-day:last-child { border-bottom: none; padding-bottom: 0; }
.plan-day:first-child { padding-top: 0; }
.plan-day-header { font-size: 0.82rem; font-weight: 700; margin-bottom: 6px; }
.plan-day-date { font-weight: 400; color: var(--color-text-muted); }

/* ---------- Objetivos activos (dashboard): grilla de tarjetas + anillo ---------- */
.goal-mini-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 6px;
}
.goal-mini-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
  padding: 7px 5px;
  border-radius: var(--radius);
  background: var(--goal-soft, var(--color-bg));
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  /* Reordenamiento por long-press+arrastre (ver wireGoalMiniGridDragDrop):
     sin esto, el gesto de agarrar la card puede quedar "peleando" con el
     scroll nativo de la página en mobile. */
  touch-action: none;
}
.goal-mini-card.dragging {
  transform: scale(1.04);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
  opacity: 0.9;
  z-index: 5;
}
.goal-mini-section-title {
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--color-text-muted);
  margin: 8px 0 4px;
}
.goal-mini-section-title:first-child { margin-top: 0; }
.goal-ring { position: relative; width: 44px; height: 44px; margin-bottom: 1px; cursor: pointer; }
.goal-ring-svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.goal-ring-track { fill: none; stroke: rgba(0, 0, 0, 0.08); stroke-width: 4; }
.goal-ring-fill {
  fill: none; stroke: var(--ring-color, var(--color-primary)); stroke-width: 4; stroke-linecap: round;
  transition: stroke-dashoffset 0.5s ease;
}
.goal-ring-emoji {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
}
.goal-ring-badge {
  position: absolute; bottom: -2px; right: -2px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--color-primary); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.55rem; font-weight: 700;
  border: 2px solid var(--color-surface);
}
.goal-mini-pct { font-size: 0.82rem; font-weight: 700; }
.goal-mini-title {
  font-size: 0.68rem; font-weight: 600; color: var(--color-text);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  width: 100%;
}
.goal-mini-sub { font-size: 0.62rem; color: var(--color-text-muted); }

/* ---------- Objetivos ---------- */
.goal-card { display: flex; flex-direction: column; gap: 6px; }
.goal-card .goal-title { font-weight: 700; }
/* Estado ("ACTIVO"/"Cumplido") + detalle del objetivo en la misma línea, para
   aprovechar el ancho y sumar menos líneas por tarjeta (menos scroll). */
.goal-status-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.goal-card .goal-meta { font-size: 0.8rem; color: var(--color-text-muted); text-align: right; min-width: 0; }
.goal-progress-bar {
  height: 8px; border-radius: 999px; background: var(--color-border); overflow: hidden;
}
.goal-progress-bar > div { height: 100%; background: var(--color-primary); }
.goal-progress-label { font-size: 0.78rem; color: var(--color-text-muted); text-align: right; }
.goal-status {
  flex-shrink: 0;
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; background: var(--color-bg); color: var(--color-text-muted);
}
.goal-status.completed { background: var(--color-success-bg); color: var(--color-primary-dark); }
.goal-status.failed { background: var(--color-danger-bg); color: var(--color-danger); }

/* Pie de la tarjeta: resumen de días/semanas cumplidos a la izquierda,
   "Archivar" siempre a la derecha, en la misma línea. */
.goal-footer-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
.goal-footer-row .btn-link { padding: 4px 0; }

/* ---------- Carga rápida ---------- */
.quick-tabs { display: flex; gap: 6px; overflow-x: auto; padding: 0 var(--gap); margin-bottom: 12px; }
.quick-tabs button {
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 999px;
  width: 46px;
  height: 46px;
  font-size: 1.4rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.quick-tabs button.active { background: var(--color-primary); border-color: var(--color-primary); }

/* ---------- Botoneras de selección (deporte, calidad, etiqueta, etc.) ---------- */
.choice-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.choice-btn {
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  border-radius: 12px;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.choice-btn .choice-emoji { font-size: 1.6rem; line-height: 1; }
.choice-btn.active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }

/* Selector de dominio al crear un objetivo */
.domain-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.domain-btn {
  flex: 1 1 28%;
  min-width: 88px;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  border-radius: 12px;
  padding: 14px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--color-text);
}
.domain-btn .choice-emoji { font-size: 1.8rem; line-height: 1; }

/* Botonera genérica de una sola opción (medición, etc.) */
.option-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.option-btn {
  flex: 1;
  min-width: 64px;
  border: 2px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 10px;
  padding: 10px 4px;
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}
.option-btn.active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }

/* Botonera de tipo con ícono + texto lado a lado (ej. Cerveza/Vino/Trago) */
.type-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.type-btn {
  flex: 1;
  min-width: 92px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  border-radius: 10px;
  padding: 13px 10px;
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
}
.type-btn .choice-emoji { font-size: 1.35rem; line-height: 1; flex-shrink: 0; }
.type-btn.active { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }

/* Calidad de comida: FIT / MASO / DERRAPE */
.quality-grid { display: flex; gap: 8px; }
.quality-btn {
  flex: 1;
  border: 2px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 10px;
  padding: 12px 4px;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.quality-btn[data-value="saludable"].active { background: var(--color-success-bg); border-color: var(--color-primary); color: var(--color-primary-dark); }
.quality-btn[data-value="moderada"].active { background: #fdf3e0; border-color: #d99a2b; color: #92650f; }
.quality-btn[data-value="no_saludable"].active { background: var(--color-danger-bg); border-color: var(--color-danger); color: var(--color-danger); }

/* ---------- Alcohol: tocar para sumar vasos ---------- */
.alcohol-tap {
  margin: 4px auto 8px;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  background: var(--color-bg);
  font-size: 2.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.alcohol-tap:active { background: var(--color-success-bg); }
.alcohol-count {
  text-align: center;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: 4px;
}
.alcohol-count-hint { text-align: center; font-size: 0.78rem; color: var(--color-text-muted); margin-bottom: 14px; }

/* ---------- Colaciones: 3 tap-counters lado a lado ---------- */
.section-divider { margin: 20px 0; border: none; border-top: 1px solid var(--color-border); }
.snack-grid { display: flex; gap: 10px; justify-content: space-around; margin: 10px 0 14px; }
.snack-tap-item { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.snack-tap {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  background: var(--color-bg);
  font-size: 1.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.snack-tap:active { background: var(--color-success-bg); }
.snack-label { font-size: 0.7rem; color: var(--color-text-muted); text-align: center; }
.snack-count { font-size: 0.9rem; font-weight: 700; }

/* ---------- Tab bar (nav inferior) ---------- */
.tab-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  display: flex;
  max-width: 480px;
  margin: 0 auto;
  /* si no, en iPhones sin botón físico el home indicator tapa la barra */
  padding-bottom: env(safe-area-inset-bottom, 0px);
  /* sin esto, los encabezados sticky de la grilla semanal del profesor
     (.week-grid-table, z-index 1-2) pintan por encima de la barra al
     scrollear la semana, tapando el ícono del tab activo */
  z-index: 10;
}
.tab-bar button {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  padding: 10px 4px 12px;
  font-size: 0.72rem;
  color: var(--color-text-muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  /* Con el tab de Profesor puede haber 6 botones en vez de 5 — sin esto, en
     un celular angosto una etiqueta larga (Planificar/Calendario/Profesor)
     se envuelve a 2 líneas y descuadra el ícono del resto de la barra. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.tab-bar button .icon { font-size: 1.25rem; }
.tab-bar button.active { color: var(--color-primary); font-weight: 700; }

/* ---------- Botón flotante de agua (solo en Inicio) ---------- */
/* Posición: por default ancla a la esquina inferior derecha de LA PANTALLA
   (fixed + right/bottom, no dentro de la columna de 480px de #app) — en
   mobile eso ya es "la pantalla" porque #app ocupa todo el ancho; en
   desktop se deja igual de simple (esquina real del viewport) en vez de
   imitar el borde de la columna, así el botón nunca queda "flotando" lejos
   del dedo si el usuario lo arrastra. El usuario puede arrastrarlo (touch o
   mouse, ver wireWaterFab): la posición elegida se guarda en localStorage y
   se re-clampea a la pantalla en cada visita a Inicio (por si cambió el
   tamaño/orientación). Sin JS o sin posición guardada, right/bottom de acá
   abajo son el default. */
.water-fab-wrap {
  position: fixed;
  right: 16px;
  bottom: calc(72px + var(--safe-bottom) + 16px); /* arriba del tab-bar fijo + safe area */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  z-index: 90;
  max-width: calc(100vw - 32px); /* el menú desplegado nunca se corta contra el borde */
}
.water-fab-wrap.dragging { z-index: 95; }
.water-fab {
  width: 56px; height: 56px;
  flex-shrink: 0;
  border-radius: 50%;
  border: none;
  background: var(--color-primary);
  color: #fff;
  font-size: 1.6rem;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  touch-action: none; /* el gesto de arrastre lo maneja JS — que el browser no intente scrollear/hacer pull-to-refresh */
  user-select: none;
}
.water-fab:active { background: var(--color-primary-dark); }
.water-fab-wrap.dragging .water-fab {
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35);
  transform: scale(1.06);
}
/* :not([hidden]) — un display explícito de autor pisaría el "display:none"
   que el navegador aplica por default al atributo hidden (toggleado por JS). */
.water-fab-menu:not([hidden]) { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.water-fab-option {
  border: none;
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-primary-dark);
  font-weight: 700;
  font-size: 0.85rem;
  padding: 10px 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  white-space: nowrap;
}
.water-fab-option:active { background: var(--color-success-bg); }

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  top: 12px; left: 50%;
  transform: translateX(-50%);
  background: var(--color-text);
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 0.85rem;
  z-index: 100;
  max-width: 90vw;
  text-align: center;
}
.toast.error { background: var(--color-danger); }

/* ---------- Calendario ---------- */
.cal-header {
  display: flex; align-items: center; justify-content: space-between;
}
.cal-header h3 { margin: 0; color: var(--color-text); font-size: 1rem; }
.cal-header .btn-link { font-size: 1.3rem; text-decoration: none; padding: 4px 12px; }
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-top: 12px;
}
.cal-weekdays {
  margin-top: 14px;
  font-size: 0.72rem;
  color: var(--color-text-muted);
  text-align: center;
  font-weight: 700;
}
.cal-cell {
  aspect-ratio: 1;
  border: none;
  border-radius: 6px;
  background: var(--color-bg);
  color: var(--color-text-muted);
  font-size: 0.78rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.cal-cell.cal-blank { background: none; }
.cal-cell.level-0 { background: var(--color-bg); }
.cal-cell.level-1 { background: #cfe9dd; color: var(--color-primary-dark); }
.cal-cell.level-2 { background: #9ed4ba; color: var(--color-primary-dark); }
.cal-cell.level-3 { background: #5fb890; color: #fff; }
.cal-cell.level-4 { background: var(--color-primary-dark); color: #fff; font-weight: 700; }
/* ---------- Grilla semanal del profesor (día × horario) ---------- */
.week-grid-wrap { overflow-x: auto; margin-top: 8px; -webkit-overflow-scrolling: touch; }
.week-grid-table { border-collapse: collapse; width: max-content; }
.week-grid-table th, .week-grid-table td { border: 1px solid var(--color-border); text-align: center; }
.week-grid-table thead th {
  position: sticky; top: 0; background: var(--color-surface);
  font-size: 0.66rem; font-weight: 700; line-height: 1.3; padding: 4px 6px; z-index: 2;
}
.week-grid-time-col {
  position: sticky; left: 0; background: var(--color-surface);
  font-size: 0.62rem; color: var(--color-text-muted); padding: 2px 6px; white-space: nowrap; z-index: 1;
}
.week-grid-cell { width: 38px; height: 22px; padding: 0; cursor: pointer; }
.week-grid-cell:active { background: var(--color-success-bg); }
.week-grid-cell.has-class { cursor: default; padding: 1px; }
.week-grid-chip {
  border: none; background: var(--color-primary); color: #fff; border-radius: 6px;
  width: 100%; height: 20px; font-size: 0.8rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}

.cal-legend {
  display: flex; align-items: center; gap: 4px; justify-content: flex-end;
  margin-top: 12px; font-size: 0.72rem; color: var(--color-text-muted);
}
.cal-legend .cal-cell { width: 14px; height: 14px; aspect-ratio: unset; border-radius: 3px; }
.cal-cell.selected { outline: 2px solid var(--color-primary-dark); outline-offset: 1px; }

.cal-day-detail-title {
  margin: 20px 0 12px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
  font-size: 0.9rem;
  font-weight: 700;
}

/* Cada grupo (Entrenamiento, Comida, Agua...) queda como su propia tarjeta
   chica, bien separada de las demás — así no se mezclan entre sí. */
.cal-day-group {
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--color-bg);
  border-radius: 10px;
}
.cal-day-group-title {
  margin: 0 0 8px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
}

.day-detail-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.85rem;
}
.cal-day-group .day-detail-row:last-child { border-bottom: none; padding-bottom: 0; }
.dd-label { font-weight: 600; }
.dd-measure { color: var(--color-text-muted); text-align: right; white-space: nowrap; flex-shrink: 0; }

/* ---------- Lista de alumnos (Profesor): nombre arriba, mail debajo — o solo el mail si nunca entró a la app ---------- */
.student-list-row {
  padding: 7px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.85rem;
  text-align: left;
}
.student-list-row:last-child { border-bottom: none; padding-bottom: 0; }
.student-name, .student-email {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.student-name { font-weight: 600; }
.student-email { color: var(--color-text-muted); font-size: 0.78rem; font-weight: 400; margin-top: 1px; }
.student-list-row.goal-footer-row { margin-top: 0; }
.student-list-row.goal-footer-row > div:first-child { flex: 1; min-width: 0; }

/* ---------- Últimos 7 días / Último mes: toggle + filtro + tabla de 4 columnas ---------- */
.week-header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.week-header select {
  width: auto;
  padding: 6px 8px;
  font-size: 0.78rem;
  border-radius: 8px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
}
/* En pantallas angostas, el toggle semana/mes y el filtro de sección no
   entran cómodos en una sola fila — se apilan para no amontonarse. */
@media (max-width: 360px) {
  .week-header { flex-direction: column; align-items: stretch; }
  .week-header select { width: 100%; }
}
.week-section { margin-top: 18px; }
.week-section:first-of-type { margin-top: 14px; }
.week-section-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 0 0 6px;
  margin: 0 0 6px;
  border-bottom: 2px solid var(--color-border);
  font-family: inherit;
  cursor: pointer;
}
.week-section-toggle h4 { font-size: 0.8rem; font-weight: 400; color: var(--color-text); margin: 0; }
.week-section-caret { color: var(--color-text-muted); font-size: 0.9rem; transition: transform 0.15s ease; }
.week-section-toggle.expanded .week-section-caret { transform: rotate(90deg); }
.week-table-wrap { overflow-x: auto; }
.week-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.week-table th {
  text-align: left;
  padding: 4px 6px;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.7rem;
  font-weight: 400;
  white-space: nowrap;
}
.week-table td { padding: 6px; border-bottom: 1px solid var(--color-border); white-space: nowrap; }
.week-table tr:last-child td { border-bottom: none; }
.week-table th:first-child, .week-table td:first-child { white-space: normal; }
.week-change.good { color: var(--color-primary-dark); font-weight: 700; }
.week-change.bad { color: var(--color-danger); font-weight: 700; }
.week-change.flat { color: var(--color-text-muted); }
.week-change.new { color: var(--color-text-muted); font-style: italic; }

/* ---------- Objetivos vs. días (Inicio, debajo de "Objetivos activos") ---------- */
.goal-grid-wrap { overflow-x: auto; }
.goal-grid-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.goal-grid-table th {
  text-align: center;
  padding: 4px 3px;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.68rem;
  font-weight: 400;
  white-space: nowrap;
}
.goal-grid-table thead tr:first-child th { font-weight: 700; border-bottom: none; }
.goal-grid-table td { border-bottom: 1px solid var(--color-border); }
.goal-grid-table tr:last-child td { border-bottom: none; }
.goal-grid-title {
  padding: 6px 8px 6px 0;
  white-space: nowrap;
  font-size: 0.78rem;
}
.goal-grid-cell { width: 22px; height: 28px; text-align: center; color: transparent; }
/* Separador visual entre las 3 semanas: col 1 = título, cols 2-8/9-15/16-22 = cada semana. */
.goal-grid-table th:nth-child(2), .goal-grid-table td:nth-child(2),
.goal-grid-table th:nth-child(9), .goal-grid-table td:nth-child(9),
.goal-grid-table th:nth-child(16), .goal-grid-table td:nth-child(16) { border-left: 2px solid var(--color-border); }
.goal-grid-green { color: var(--color-primary); font-weight: 700; }
.goal-grid-yellow { color: #d99a2b; font-weight: 700; }
.goal-grid-red { color: var(--color-danger); font-weight: 700; }
.goal-grid-planned { color: #c3c9c6; }
.goal-grid-table tfoot td { padding-top: 8px; border-top: 2px solid var(--color-border); border-bottom: none; }
.goal-grid-week-total { text-align: center; font-weight: 700; }

/* ---------- Evolución de peso (Inicio, debajo de todo) ---------- */
.weight-chart-wrap { margin-top: 8px; }
.weight-chart-svg { width: 100%; height: auto; display: block; touch-action: manipulation; }
.weight-chart-grid { stroke: var(--color-border); stroke-width: 1; }
.weight-chart-area { fill: var(--color-primary); fill-opacity: 0.1; stroke: none; }
.weight-chart-line { fill: none; stroke: var(--color-primary); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.weight-chart-dot { fill: var(--color-primary); stroke: var(--color-surface); stroke-width: 2; cursor: pointer; }
.weight-chart-dot.last { fill: var(--color-primary-dark); }
.weight-chart-axis-label { font-size: 7px; fill: var(--color-text-muted); }
.weight-chart-end-label { font-size: 9px; font-weight: 700; fill: var(--color-text); }
.weight-chart-range { display: flex; justify-content: space-between; font-size: 0.7rem; color: var(--color-text-muted); margin-top: 2px; padding: 0 2px; }

/* ---------- Tablero oculto: todos los registros ---------- */
.records-filters { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.records-filters select, .records-filters input { width: 100%; }
.records-table-wrap { overflow-x: auto; }
.records-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.records-table th {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 2px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.72rem;
  white-space: nowrap;
}
.records-table td { padding: 7px 8px; border-bottom: 1px solid var(--color-border); white-space: nowrap; }
.records-table td:nth-child(1) { white-space: nowrap; }
.records-table td:nth-child(3) { white-space: normal; min-width: 160px; }

.empty-state { color: var(--color-text-muted); font-size: 0.88rem; text-align: center; padding: 20px 0; }
.spinner { text-align: center; color: var(--color-text-muted); padding: 24px; font-size: 0.9rem; }

/* ---------- Encabezado de Inicio: avatar a la izquierda, datos a la derecha ---------- */
.body-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.body-info-name { font-size: 1rem; }
.body-info-age { font-size: 0.82rem; font-weight: 400; color: var(--color-text-muted); }
.body-info-line { font-size: 0.85rem; color: var(--color-text); }
.body-info-line.body-info-muted { color: var(--color-text-muted); font-size: 0.82rem; }

/* ---------- Checkbox "semana de lunes a domingo" (Objetivos) ---------- */
.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--color-text);
  margin-top: 4px;
}
.checkbox-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 1px 0 0;
  flex-shrink: 0;
  border-radius: 4px;
}

/* ---------- Picker de "a quién va" una clase (buscador + checklist scrolleable, ver openClassModal) ---------- */
.attendee-picker-list {
  max-height: 180px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  padding: 8px 10px;
  margin: 6px 0 12px;
}
.attendee-picker-list .checkbox-row { margin-top: 6px; }
.attendee-picker-list .checkbox-row:first-child { margin-top: 0; }

/* ---------- Objetivos: tarjeta clickeable para editar + desglose semanal ---------- */
.goal-card[data-goal-id] { cursor: pointer; }
.goal-card[data-goal-id]:active { background: var(--color-bg); }
.goal-weeks-summary { font-size: 0.78rem; font-weight: 700; color: var(--color-text); margin: 0; }

/* ---------- Drill-down de cargas: tiles/checklist/filas de tabla clickeables ---------- */
.stat-tile[data-metric] { cursor: pointer; }
.stat-tile[data-metric]:active { background: var(--color-border); }
.checklist li[data-check] { cursor: pointer; }
.metric-row { cursor: pointer; }
.metric-row:active td { background: var(--color-bg); }

/* ---------- Modal de drill-down (cargas de una métrica) ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 200;
}
.modal-panel {
  width: 100%;
  max-width: 480px;
  max-height: 82vh;
  overflow-y: auto;
  background: var(--color-surface);
  border-radius: 18px 18px 0 0;
  padding: var(--gap);
  padding-bottom: calc(var(--gap) + env(safe-area-inset-bottom, 0px));
}
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.modal-header h3 { font-size: 1rem; color: var(--color-text); margin: 0; }
.modal-close {
  background: var(--color-bg);
  border: none;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  font-size: 0.9rem;
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-body .day-detail-row:last-child { border-bottom: none; }
