/* =========================================================================
   MAGNUS. — Design System
   Negro carbón + glass + acento plateado + bento grid.
   ========================================================================= */

@font-face {
  font-family: "Coolvetica";
  src: url("../public/fonts/Coolvetica.woff2") format("woff2"),
       url("../public/fonts/Coolvetica.otf") format("opentype");
  font-weight: 400 800;
  font-display: swap;
}

:root {
  --bg-primary: #050506;
  --bg-secondary: #101012;
  --bg-card: #17181b;
  --bg-card-hover: #1d1e22;
  --border-subtle: rgba(255, 255, 255, 0.10);
  --border-glass: rgba(255, 255, 255, 0.18);
  /* Plata brillante: reservada para lo que tiene que resaltar. Es lo que
     hace la jerarquía, ya que la paleta no usa color. */
  --accent-bright: #f0f3f6;
  --text-primary: #ffffff;
  --text-secondary: #a3a3a3;
  --text-muted: #6b6b6b;
  --accent: #cdd3da;
  --accent-soft: rgba(205, 211, 218, 0.15);
  --accent-glow: rgba(205, 211, 218, 0.45);
  --accent-ink: #14171a;
  --danger: #ff6b6b;
  --danger-soft: rgba(255, 107, 107, 0.15);
  --warning: #f4c95d;
  --warning-soft: rgba(244, 201, 93, 0.15);

  --radius-lg: 24px;
  --radius-md: 16px;
  --radius-sm: 12px;
  --radius-pill: 999px;

  --font-display: "Coolvetica", "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body: "Inter", "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, sans-serif;

  --shadow-card: 0 14px 40px rgba(0,0,0,0.45);

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

* { box-sizing: border-box; }
html { color-scheme: dark; }
html, body { height: 100%; }
body {
  margin: 0;
  /* Un negro plano deja la app muerta. Dos focos de plata muy tenues, uno
     arriba a la izquierda y otro abajo a la derecha, le dan profundidad
     sin ensuciar el fondo ni salirse de blanco/negro/plateado. */
  background:
    radial-gradient(1100px 700px at 12% -8%, rgba(205,211,218,0.07), transparent 62%),
    radial-gradient(900px 600px at 92% 106%, rgba(205,211,218,0.05), transparent 58%),
    var(--bg-primary);
  background-attachment: fixed;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.035em; margin: 0; }
/* Degradado sutil blanco → gris claro — solo en los títulos grandes (h1/h2) */
h1, h2 {
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 35%, #989ca1 100%);
  background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; color: #ffffff;
}
h1 { font-size: 44px; line-height: 1.08; }
h2 { font-size: 30px; line-height: 1.15; }
h3 { font-size: 20px; line-height: 1.25; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: var(--font-body); }
ul { margin: 0; padding: 0; list-style: none; }
::selection { background: var(--accent-glow); color: #0a0a0a; }

/* Scrollbars */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.2); }

/* -------------------------------------------------------------------- */
/* Utilidades de layout                                                  */
/* -------------------------------------------------------------------- */
#app-root { width: 100%; }
/* El armazón ocupa la pantalla y NO se mueve: lo que hace scroll es solo
   el contenido. Antes crecía con la página y arrastraba consigo la barra
   lateral y la superior, que acababan pegadas abajo con un hueco negro
   arriba en cuanto una pantalla era más alta que la ventana. */
.app-shell { display: flex; height: 100vh; width: 100%; overflow: hidden; }
.main-area { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.content { padding: 32px 40px 60px; width: 100%; flex: 1; min-height: 0; overflow-y: auto; }
.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 24px; flex-wrap: wrap; }
.page-header .eyebrow { color: var(--accent); font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 6px; display: block; }
.page-header p.subtitle { color: var(--text-secondary); margin-top: 6px; font-size: 14.5px; }
.header-actions { display: flex; gap: 10px; align-items: center; }

.bento-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.bento-grid .bento-grid { gap: 14px; }
.col-1 { grid-column: span 1; }
.col-2 { grid-column: span 2; }
.col-3 { grid-column: span 3; }
.col-4 { grid-column: span 4; }
.row-2 { grid-row: span 2; }
@media (max-width: 1100px) {
  .bento-grid { grid-template-columns: repeat(2, 1fr); }
  .col-3 { grid-column: span 2; }
}
@media (max-width: 640px) {
  .bento-grid { grid-template-columns: 1fr; }
  .col-1, .col-2, .col-3, .col-4 { grid-column: span 1; }
  .content { padding: 20px 16px 48px; }
}

.stack { display: flex; flex-direction: column; }
/* Escala de espaciado COMPLETA. Estaba salteada — faltaban gap-6, gap-10,
   gap-14, mt-4, mt-14 y mb-20 — y usar una clase inexistente no da error:
   simplemente no separa, y los elementos salen pegados. Definirla entera
   cierra esa clase de fallo de una vez. */
.gap-2 { gap: 2px; } .gap-4 { gap: 4px; } .gap-6 { gap: 6px; } .gap-8 { gap: 8px; } .gap-10 { gap: 10px; } .gap-12 { gap: 12px; } .gap-14 { gap: 14px; } .gap-16 { gap: 16px; } .gap-18 { gap: 18px; } .gap-20 { gap: 20px; } .gap-24 { gap: 24px; } .gap-28 { gap: 28px; } .gap-32 { gap: 32px; }

.row { display: flex; align-items: center; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* Sin esto, un nombre/etiqueta largo dentro de una fila flex no se encoge:
   se sale de la tarjeta y se solapa con la tarjeta/columna vecina. */
.row > *, .row-between > * { min-width: 0; }
.flex-1 { flex: 1; min-width: 0; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.muted { color: var(--text-secondary); }
.text-muted-2 { color: var(--text-muted); }
.text-accent { color: var(--accent); }
.text-danger { color: var(--danger); }
.text-warning { color: var(--warning); }
.text-xs { font-size: 12px; }
.text-sm { font-size: 13.5px; }
.mt-2 { margin-top: 2px; } .mt-4 { margin-top: 4px; } .mt-6 { margin-top: 6px; } .mt-8 { margin-top: 8px; } .mt-10 { margin-top: 10px; } .mt-12 { margin-top: 12px; } .mt-14 { margin-top: 14px; } .mt-16 { margin-top: 16px; } .mt-18 { margin-top: 18px; } .mt-20 { margin-top: 20px; } .mt-24 { margin-top: 24px; } .mt-28 { margin-top: 28px; } .mt-32 { margin-top: 32px; }
.mb-2 { margin-bottom: 2px; } .mb-4 { margin-bottom: 4px; } .mb-6 { margin-bottom: 6px; } .mb-8 { margin-bottom: 8px; } .mb-10 { margin-bottom: 10px; } .mb-12 { margin-bottom: 12px; } .mb-14 { margin-bottom: 14px; } .mb-16 { margin-bottom: 16px; } .mb-18 { margin-bottom: 18px; } .mb-20 { margin-bottom: 20px; } .mb-24 { margin-bottom: 24px; } .mb-28 { margin-bottom: 28px; } .mb-32 { margin-bottom: 32px; }

/* -------------------------------------------------------------------- */
/* Glass / Bento card                                                    */
/* -------------------------------------------------------------------- */
.card {
  background:
    linear-gradient(160deg, rgba(255,255,255,0.13) 0%, rgba(255,255,255,0.05) 26%, rgba(255,255,255,0.018) 62%, rgba(255,255,255,0.008) 100%),
    var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(24px) saturate(1.2);
  padding: 22px;
  box-shadow: var(--shadow-card), inset 0 1px 0 rgba(255,255,255,0.12), inset 0 -1px 0 rgba(0,0,0,0.35);
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease), background 0.2s var(--ease);
  position: relative;
  overflow: hidden;
}
/* El filo de luz del borde superior: es lo que hace que una tarjeta se lea
   como cristal y no como un rectángulo gris. Se desvanece hacia los lados
   igual que lo haría un reflejo real. */
.card::before {
  content: ""; position: absolute; top: 0; left: 8%; right: 8%; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.55), transparent);
  pointer-events: none;
}
/* Segundo reflejo: un barrido diagonal muy tenue por la esquina superior
   izquierda. Es lo que separa "oscuro con borde" de "cristal". */
.card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(135deg, rgba(255,255,255,0.09) 0%, transparent 30%);
}
.card:hover { border-color: var(--border-glass); background-color: var(--bg-card-hover); }
.card:hover::before { left: 3%; right: 3%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.75), transparent); }
.card.interactive:hover { transform: translateY(-2px) scale(1.01); box-shadow: 0 16px 40px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.09); }

/* "Featured" = lo que manda ahora mismo en la pantalla. Borde de plata,
   halo alrededor y un foco interior arriba a la izquierda. */
.card.featured {
  border-color: rgba(205,211,218,0.55);
  background:
    radial-gradient(560px 240px at 6% -14%, rgba(205,211,218,0.26), transparent 68%),
    linear-gradient(160deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.06) 30%, rgba(255,255,255,0.015) 100%),
    var(--bg-card);
  box-shadow: 0 0 70px rgba(205,211,218,0.2), var(--shadow-card), inset 0 1px 0 rgba(255,255,255,0.28);
}
.card.featured::before { left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.95), transparent); }
.card.featured::after { background: linear-gradient(135deg, rgba(255,255,255,0.14) 0%, transparent 34%); }
.card.glow-hover:hover { box-shadow: 0 0 40px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,0.09); }
.card.pad-sm { padding: 16px; }
.card.pad-lg { padding: 28px; }
.card.no-hover:hover { transform:none; background-color: var(--bg-card); border-color: var(--border-subtle); }

.kpi-label { color: var(--text-secondary); font-size: 12.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.kpi-value {
  font-family: var(--font-display); font-size: 34px; font-weight: 700; margin-top: 6px; letter-spacing: -0.035em;
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 40%, #9aa5b1 100%);
  background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
/* Para cualquier cifra grande fuera de los KPI: la nota del IPP, el total
   de créditos, la brecha... */
.big-number {
  font-family: var(--font-display); font-weight: 700; letter-spacing: -0.035em; line-height: 1;
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 40%, #9aa5b1 100%);
  background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.kpi-delta { font-size: 12.5px; font-weight: 600; margin-top: 4px; display: inline-flex; align-items: center; gap: 4px; }
.kpi-delta.up { color: var(--accent); }
.kpi-delta.down { color: var(--danger); }

/* Accesos rápidos del dashboard: mosaico grande de todas las herramientas */
.quick-access-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.quick-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  text-align: center; padding: 22px 12px; border-radius: var(--radius-md); background: rgba(255,255,255,0.03);
  border: 1px solid var(--border-subtle); transition: all 0.2s var(--ease); min-height: 118px;
}
.quick-tile span { font-size: 13px; font-weight: 700; line-height: 1.25; }
.quick-tile-icon { width: 46px; height: 46px; border-radius: 14px; display: flex; align-items: center; justify-content: center; background: var(--accent-soft); color: var(--accent); transition: all 0.2s var(--ease); }
.quick-tile:hover { transform: translateY(-3px); border-color: var(--border-glass); background: rgba(255,255,255,0.06); box-shadow: 0 12px 28px rgba(0,0,0,0.3); }
.quick-tile:hover .quick-tile-icon { box-shadow: 0 0 22px var(--accent-glow); transform: scale(1.06); }
.quick-tile.active { border-color: rgba(205,211,218,0.4); background: var(--accent-soft); }

/* -------------------------------------------------------------------- */
/* Botones                                                               */
/* -------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: var(--radius-sm); border: 1px solid transparent; cursor: pointer;
  font-size: 14px; font-weight: 600; padding: 11px 18px; transition: all 0.2s var(--ease);
  white-space: nowrap; user-select: none;
}
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: linear-gradient(180deg, var(--accent-bright) 0%, var(--accent) 55%, #b4bcc5 100%);
  color: var(--accent-ink);
  box-shadow: 0 2px 14px rgba(205,211,218,0.28), inset 0 1px 0 rgba(255,255,255,0.85);
  border: 1px solid rgba(255,255,255,0.22);
}
.btn-primary:hover { box-shadow: 0 0 28px var(--accent-glow); transform: translateY(-1px); }
.btn-secondary { background: rgba(255,255,255,0.05); color: var(--text-primary); border-color: var(--border-glass); backdrop-filter: blur(10px); }
.btn-secondary:hover { background: rgba(255,255,255,0.09); }
.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover { color: var(--text-primary); background: rgba(255,255,255,0.05); }
.btn-danger { background: var(--danger-soft); color: var(--danger); border-color: rgba(255,107,107,0.3); }
.btn-danger:hover { background: rgba(255,107,107,0.25); }
.btn-sm { padding: 7px 12px; font-size: 12.5px; border-radius: 10px; }
.btn-icon { padding: 9px; border-radius: 10px; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform:none; box-shadow:none; }
.btn svg { width: 16px; height: 16px; }

/* -------------------------------------------------------------------- */
/* Inputs                                                                */
/* -------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 12.5px; color: var(--text-secondary); font-weight: 600; }
.input, .textarea, select.input {
  background: rgba(255,255,255,0.04); border: 1px solid var(--border-glass); color: var(--text-primary);
  border-radius: var(--radius-sm); padding: 11px 14px; font-size: 14px; font-family: var(--font-body);
  outline: none; transition: all 0.2s var(--ease); width: 100%;
}
/* Campos de tabla: más pequeños para que quepan las columnas. El tamaño
   vive aquí y no en la etiqueta, porque un estilo escrito en la etiqueta
   gana a cualquier regla y se saltaba el mínimo del móvil. */
.input-compacto { font-size: 12.5px; }

/* -------------------------------------------------------------------------
   Por qué 16 píxeles en el móvil

   Safari en iPhone amplía la página él solo en cuanto tocas un campo cuya
   letra mide menos de 16 píxeles. Y no vuelve a su sitio al salir del campo:
   se queda ampliada, así que después de escribir el correo toda la
   aplicación aparece con un zoom que hay que deshacer a mano.

   Se arregla subiendo la letra, no bloqueando el zoom en el `viewport`: eso
   último le quitaría a cualquiera la posibilidad de ampliar para leer, y en
   iOS moderno además se ignora.
   ------------------------------------------------------------------------- */
@media (max-width: 900px), (pointer: coarse) {
  .input, .textarea, select.input, .input-compacto, .topbar-search input,
  input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="search"], input[type="date"],
  input[type="time"], textarea, select {
    font-size: 16px;
  }
}

.input::placeholder, .textarea::placeholder { color: var(--text-muted); }
.input:focus, .textarea:focus, select.input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); background: rgba(255,255,255,0.06); }
.textarea { resize: vertical; min-height: 90px; line-height: 1.5; }
/* El desplegable nativo de <select> no hereda el fondo oscuro de la app:
   sin esto, el navegador lo pinta blanco con texto blanco heredado
   (ilegible hasta pasar el cursor, que fuerza el resaltado). */
select.input, select { color-scheme: dark; }
select.input option, select option { background: #1a1a1a; color: #ffffff; }
.checkbox { width: 20px; height: 20px; border-radius: 6px; border: 1.5px solid var(--border-glass); background: rgba(255,255,255,0.03); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; transition: all 0.15s var(--ease); }
.checkbox.checked { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 14px var(--accent-glow); }
.checkbox svg { width: 13px; height: 13px; color: var(--accent-ink); }

/* -------------------------------------------------------------------- */
/* Badges / pills                                                        */
/* -------------------------------------------------------------------- */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: var(--radius-pill); font-size: 11.5px; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; }
.badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* Un icono delante de un texto DENTRO de un párrafo o de una etiqueta no
   tiene flex que lo separe, así que queda encajado contra la palabra y
   descuadrado respecto a la línea base. Los `.badge` y las filas `.row`
   ya lo resuelven con su propio `gap`; esto cubre el resto de sitios. */
p > .lucide,
.kpi-label > .lucide,
span.text-xs:not(.badge) > .lucide,
span.text-sm:not(.badge) > .lucide {
  display: inline-block;
  vertical-align: -0.16em;
  margin-right: 6px;
}
.badge.accent { background: linear-gradient(180deg, rgba(205,211,218,0.22), rgba(205,211,218,0.1)); color: #e8ecf0; box-shadow: inset 0 1px 0 rgba(255,255,255,0.16); }
.badge.warning { background: var(--warning-soft); color: var(--warning); }
.badge.danger { background: var(--danger-soft); color: var(--danger); }
.badge.neutral { background: rgba(255,255,255,0.08); color: var(--text-secondary); }

/* Selector de color de interfaz */
.theme-swatch {
  width: 42px; height: 42px; border-radius: 50%; border: 2px solid transparent; cursor: pointer;
  position: relative; overflow: hidden; transition: transform 0.15s var(--ease), border-color 0.15s var(--ease);
  display: inline-flex; align-items: center; justify-content: center;
}
.theme-swatch:hover { transform: scale(1.08); }
.theme-swatch.active { border-color: #fff; box-shadow: 0 0 0 3px rgba(255,255,255,0.15); }
.theme-swatch-custom { border-color: var(--border-glass); }

/* Avatar */
.avatar { width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; color: var(--accent-ink); background: var(--accent); flex-shrink: 0; }
.avatar.sm { width: 26px; height: 26px; font-size: 11px; }
.avatar.lg { width: 56px; height: 56px; font-size: 18px; }
.avatar.xl { width: 84px; height: 84px; font-size: 26px; }

/* -------------------------------------------------------------------- */
/* Progreso                                                               */
/* -------------------------------------------------------------------- */
.progress-bar { height: 8px; border-radius: var(--radius-pill); background: rgba(255,255,255,0.06); overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,0.4); }
/* De plata apagada a plata clara: la barra "gana luz" según avanza, que es
   justo lo que se quiere transmitir. */
.progress-bar-fill {
  height: 100%; border-radius: var(--radius-pill);
  background: linear-gradient(90deg, #5c6673 0%, #9aa5b1 40%, var(--accent-bright) 100%);
  box-shadow: 0 0 18px rgba(205,211,218,0.6), inset 0 1px 0 rgba(255,255,255,0.75);
  transition: width 0.4s var(--ease);
}
.progress-bar.sm { height: 5px; }

.ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.ring svg circle { transition: stroke-dashoffset 0.6s var(--ease); }
.ring-label { position: absolute; text-align: center; }
.ring-label .big { font-family: var(--font-display); font-size: 26px; font-weight: 700; }
.ring-label .small { font-size: 11px; color: var(--text-secondary); }

/* -------------------------------------------------------------------- */
/* Tabs                                                                   */
/* -------------------------------------------------------------------- */
.tabs { display: inline-flex; background: rgba(255,255,255,0.04); border: 1px solid var(--border-subtle); border-radius: var(--radius-pill); padding: 4px; gap: 2px; }
/* En el móvil, cinco o seis pestañas no caben en una fila de 375 px y las
   últimas se salían de la pantalla. Se arrastran con el dedo. */
@media (max-width: 900px) {
  .tabs { display: flex; max-width: 100%; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { flex: 0 0 auto; white-space: nowrap; padding: 8px 13px; }
}
.tab { padding: 8px 16px; border-radius: var(--radius-pill); font-size: 13px; font-weight: 600; color: var(--text-secondary); cursor: pointer; transition: all 0.2s var(--ease); }
.tab.active { background: var(--accent); color: var(--accent-ink); }
.tab:not(.active):hover { color: var(--text-primary); }

/* -------------------------------------------------------------------- */
/* Tabla                                                                  */
/* -------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; border-radius: var(--radius-md); border: 1px solid var(--border-subtle); }
table.data-table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 640px; }
table.data-table th { text-align: left; color: var(--text-secondary); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; padding: 12px 16px; background: rgba(255,255,255,0.03); border-bottom: 1px solid var(--border-subtle); white-space: nowrap; }
table.data-table td { padding: 13px 16px; border-bottom: 1px solid var(--border-subtle); vertical-align: middle; }
table.data-table tr:last-child td { border-bottom: none; }
table.data-table tbody tr { transition: background 0.15s var(--ease); cursor: default; }
table.data-table tbody tr.clickable { cursor: pointer; }
table.data-table tbody tr.clickable:hover { background: rgba(255,255,255,0.035); }

/* -------------------------------------------------------------------- */
/* Modal / drawer                                                         */
/* -------------------------------------------------------------------- */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); backdrop-filter: blur(4px); z-index: 80; display: flex; align-items: center; justify-content: center; animation: fadeIn 0.15s var(--ease); }
.modal { width: 100%; max-width: 520px; max-height: 86vh; overflow-y: auto; background: #171717; border: 1px solid var(--border-glass); border-radius: var(--radius-lg); padding: 26px; box-shadow: 0 20px 60px rgba(0,0,0,0.5); animation: popIn 0.18s var(--ease); }
.modal.lg { max-width: 760px; }
.drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); backdrop-filter: blur(3px); z-index: 80; }
.drawer { position: fixed; top: 0; right: 0; height: 100vh; width: min(460px, 100vw); background: #131313; border-left: 1px solid var(--border-glass); z-index: 81; padding: 26px; overflow-y: auto; animation: slideIn 0.22s var(--ease); }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes slideIn { from { transform: translateX(24px); opacity: 0.6; } to { transform: translateX(0); opacity: 1; } }

/* Tooltip */
.tooltip { position: relative; }
.tooltip[data-tip]:hover::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  background: #222; color: #fff; padding: 6px 10px; border-radius: 8px; font-size: 11.5px; white-space: nowrap;
  border: 1px solid var(--border-glass); z-index: 40; pointer-events: none;
}

/* Toast */
.toast-stack { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 10px; z-index: 100; }
.toast { background: #181818; border: 1px solid var(--border-glass); border-radius: var(--radius-sm); padding: 13px 16px; min-width: 260px; display: flex; align-items: center; gap: 10px; box-shadow: 0 12px 30px rgba(0,0,0,0.4); animation: slideUp 0.2s var(--ease); }
.toast.success { border-left: 3px solid var(--accent); }
.toast.error { border-left: 3px solid var(--danger); }
@keyframes slideUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* Skeleton */
.skeleton { background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.09) 37%, rgba(255,255,255,0.04) 63%); background-size: 400% 100%; animation: shimmer 1.4s ease infinite; border-radius: 8px; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* =========================================================================
   SIDEBAR / TOPBAR
   ========================================================================= */
/* Ya no necesita `sticky`: vive fuera del área que hace scroll. */
.sidebar { width: 248px; flex-shrink: 0; background: var(--bg-secondary); border-right: 1px solid var(--border-subtle); display: flex; flex-direction: column; padding: 20px 14px; height: 100%; }
.sidebar-logo { font-family: var(--font-display); font-size: 22px; font-weight: 700; padding: 8px 10px 20px; letter-spacing: -0.04em; }
.sidebar-logo span { color: var(--accent); }
.sidebar-nav { display: flex; flex-direction: column; gap: 3px; flex: 1; overflow-y: auto; }
.sidebar-section-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); padding: 16px 12px 6px; font-weight: 700; }
.nav-item { display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 12px; color: var(--text-secondary); font-size: 13.5px; font-weight: 600; cursor: pointer; transition: all 0.15s var(--ease); position: relative; }
.nav-item svg { width: 18px; height: 18px; flex-shrink: 0; }
.nav-item:hover { background: rgba(255,255,255,0.05); color: var(--text-primary); }
.nav-item.active {
  background: linear-gradient(180deg, rgba(205,211,218,0.22), rgba(205,211,218,0.08));
  color: var(--accent-bright);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
}
.nav-item.active svg { filter: drop-shadow(0 0 6px var(--accent-glow)); }
.nav-item .count { margin-left: auto; background: rgba(255,255,255,0.08); color: var(--text-secondary); font-size: 10.5px; font-weight: 700; padding: 2px 7px; border-radius: 999px; }
.nav-item.active .count { color: var(--accent-ink); background: var(--accent); }
.sidebar-footer { border-top: 1px solid var(--border-subtle); padding-top: 12px; margin-top: 8px; }
.user-chip { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 12px; cursor: pointer; transition: background 0.15s var(--ease); }
.user-chip:hover { background: rgba(255,255,255,0.05); }
.user-chip .name { font-size: 13px; font-weight: 700; }
.user-chip .role { font-size: 11px; color: var(--text-muted); }

.topbar { display: flex; align-items: center; justify-content: space-between; padding: 14px 32px; border-bottom: 1px solid var(--border-subtle); background: rgba(10,10,10,0.7); backdrop-filter: blur(14px); flex-shrink: 0; z-index: 30; }
.topbar-search { display: flex; align-items: center; gap: 8px; background: rgba(255,255,255,0.04); border: 1px solid var(--border-subtle); border-radius: var(--radius-pill); padding: 8px 14px; width: 320px; color: var(--text-muted); font-size: 13px; }
.topbar-search input { background: transparent; border: none; outline: none; color: var(--text-primary); font-size: 13px; width: 100%; }
/* El mismo mínimo de 16 px que el resto de campos. Va aquí, después de
   la regla de arriba, porque con la misma especificidad gana la última:
   puesta antes, no se aplicaba. En pantallas estrechas el buscador está
   escondido, pero en una tableta apaisada sí se ve y sí se toca. */
@media (pointer: coarse) { .topbar-search input { font-size: 16px; } }
.topbar-right { display: flex; align-items: center; gap: 14px; }
.icon-btn { width: 38px; height: 38px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-secondary); background: rgba(255,255,255,0.04); border: 1px solid var(--border-subtle); cursor: pointer; transition: all 0.15s var(--ease); position: relative; }
.icon-btn:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn .dot { position: absolute; top: 7px; right: 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 6px rgba(255,107,107,0.5); }

/* -------------------------------------------------------------------------
   La navegación en el móvil

   Antes la barra lateral se escondía fuera de la pantalla y se sacaba con un
   botón. El botón, además, llevaba `display:none` escrito en la propia
   etiqueta, así que ninguna regla de aquí podía enseñarlo: en el móvil no
   había forma de moverse por la aplicación.

   Se cambia el planteamiento: fuera la barra lateral y las mismas secciones
   arriba, en una tira horizontal que se arrastra con el dedo. Un menú
   escondido detrás de un botón deja la aplicación sin rumbo —entras y no ves
   a dónde puedes ir—; en una tira está todo a la vista desde el principio.
   ------------------------------------------------------------------------- */
.topbar-logo { display: none; font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -0.04em; }
.topbar-logo span { color: var(--accent); }

.nav-movil { display: none; }
.nav-movil-item {
  display: flex; align-items: center; gap: 7px; flex-shrink: 0;
  padding: 11px 4px 9px; color: var(--text-muted);
  font-size: 13px; font-weight: 600; white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.nav-movil-item.active { color: var(--text-primary); border-bottom-color: var(--accent); }

@media (max-width: 900px) {
  .sidebar { display: none; }
  .topbar { padding: 12px 16px; }
  .topbar-logo { display: block; }
  /* La búsqueda se lleva todo el ancho y deja al logo sin sitio. En el
     móvil se cede el espacio a saber dónde estás, que importa más. */
  .topbar-search { display: none; }

  .nav-movil {
    display: flex; gap: 20px; align-items: stretch;
    padding: 0 16px; flex-shrink: 0;
    border-bottom: 1px solid var(--border-subtle);
    background: rgba(10,10,10,0.7);
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .nav-movil::-webkit-scrollbar { display: none; }

  /* Nada puede desbordar a lo ancho: cuando pasa, la página entera se
     desplaza de lado y el contenido aparece cortado por la izquierda. */
  .content { overflow-x: hidden; }
}

/* Paneles flotantes: resultados de búsqueda y notificaciones */
.topbar-search { position: relative; }
.floating-panel {
  position: absolute; top: calc(100% + 10px); left: 0; width: 340px; max-height: 420px; overflow-y: auto;
  background: #171717; border: 1px solid var(--border-glass); border-radius: var(--radius-md);
  box-shadow: 0 20px 50px rgba(0,0,0,0.5); z-index: 60; padding: 8px; animation: popIn 0.15s var(--ease);
}
.floating-panel.notif { left: auto; right: 0; width: 360px; }
.floating-group-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); font-weight: 700; padding: 8px 10px 4px; }
.floating-item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 10px; cursor: pointer; transition: background 0.15s var(--ease); }
.floating-item:hover { background: rgba(255,255,255,0.06); }
.floating-empty { padding: 18px 12px; text-align: center; color: var(--text-muted); font-size: 12.5px; }

/* =========================================================================
   LOGIN
   ========================================================================= */
.login-screen { min-height: 100vh; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; padding: 20px; background: #050505; }
.login-bg { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.login-bg::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 30%, #050505 92%); pointer-events: none; }
.login-wave { position: absolute; inset: -10% -5%; width: 110%; height: 120%; opacity: 0.9; }
.wave-layer { transform-origin: 50% 50%; }
.wave-1 { animation: waveDrift1 28s ease-in-out infinite; }
.wave-2 { animation: waveDrift2 22s ease-in-out infinite; opacity: 0.8; }
@keyframes waveDrift1 {
  0%   { transform: translate(-9%, 3%) scale(1) rotate(-2deg); }
  50%  { transform: translate(9%, -10%) scale(1.18) rotate(2deg); }
  100% { transform: translate(-9%, 3%) scale(1) rotate(-2deg); }
}
@keyframes waveDrift2 {
  0%   { transform: translate(7%, 6%) rotate(1deg); }
  50%  { transform: translate(-10%, -8%) scale(1.1) rotate(-1.5deg); }
  100% { transform: translate(7%, 6%) rotate(1deg); }
}
.login-blob { position: absolute; border-radius: 50%; filter: blur(70px); pointer-events: none; mix-blend-mode: screen; }
.blob-1 { width: 56vw; height: 56vw; max-width: 720px; max-height: 720px; top: -18%; left: -12%; background: radial-gradient(circle, rgba(205,211,218,0.55), transparent 68%); animation: driftBlob1 30s ease-in-out infinite; }
.blob-2 { width: 42vw; height: 42vw; max-width: 560px; max-height: 560px; bottom: -16%; right: -10%; background: radial-gradient(circle, rgba(205,211,218,0.4), transparent 68%); animation: driftBlob2 36s ease-in-out infinite; animation-delay: -6s; }
.blob-3 { width: 26vw; height: 26vw; max-width: 360px; max-height: 360px; top: 38%; left: 44%; background: radial-gradient(circle, rgba(255,255,255,0.16), transparent 70%); animation: driftBlob3 24s ease-in-out infinite; animation-delay: -3s; }
@keyframes driftBlob1 {
  0%   { transform: translate(0, 0) scale(1); }
  25%  { transform: translate(16%, -14%) scale(1.22); }
  50%  { transform: translate(6%, 12%) scale(0.9); }
  75%  { transform: translate(-14%, -6%) scale(1.1); }
  100% { transform: translate(0, 0) scale(1); }
}
@keyframes driftBlob2 {
  0%   { transform: translate(0, 0) scale(1); }
  30%  { transform: translate(-18%, 10%) scale(1.15); }
  60%  { transform: translate(8%, -16%) scale(0.85); }
  100% { transform: translate(0, 0) scale(1); }
}
@keyframes driftBlob3 {
  0%   { transform: translate(0, 0) scale(1); }
  40%  { transform: translate(-20%, 18%) scale(1.3); }
  70%  { transform: translate(16%, -10%) scale(0.8); }
  100% { transform: translate(0, 0) scale(1); }
}
.login-card { width: 100%; max-width: 400px; position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .wave-1, .wave-2, .login-blob { animation: none; }
}

/* -------------------------------------------------------------------------
   El fondo, en el móvil

   Este fondo son tres círculos con un desenfoque de 70 píxeles y dos capas
   de SVG con otro desenfoque encima, y las cinco se mueven. Un desenfoque
   quieto se dibuja UNA vez y luego sale gratis; en movimiento hay que
   recalcularlo en cada fotograma, y en un móvil eso se come la pantalla
   entera: la onda va a saltos y el teclado escribe con retraso, porque el
   navegador está ocupado repintando el fondo en lugar de atenderte.

   Así que en el móvil el fondo se queda quieto. Se ve igual —el desenfoque
   y los degradados siguen ahí—, solo que no se mueve. Se quita también la
   mezcla de capas, que obliga a recomponer por encima de todo lo demás, y
   el tercer círculo, que es el que menos aporta.

   `pointer: coarse` coge móviles y tabletas aunque la pantalla sea ancha:
   con el ancho solo se escapaban.
   ------------------------------------------------------------------------- */
@media (max-width: 900px), (pointer: coarse) {
  .wave-1, .wave-2, .login-blob { animation: none; }
  .login-blob { mix-blend-mode: normal; filter: blur(44px); opacity: 0.85; }
  .blob-3 { display: none; }
}
.login-logo { text-align: center; font-family: var(--font-display); font-size: 48px; font-weight: 700; letter-spacing: -0.04em; margin-bottom: 28px; }
.login-logo span { color: var(--danger); }
.demo-banner { margin-top: 18px; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--accent-soft); border: 1px solid rgba(205,211,218,0.25); font-size: 12px; color: var(--accent); }
.demo-banner .cred { display: flex; justify-content: space-between; padding: 4px 0; color: var(--text-secondary); font-family: monospace; }
.demo-banner .cred b { color: var(--text-primary); }
.demo-banner .fill-btn { color: var(--accent); cursor: pointer; text-decoration: underline; font-family: var(--font-body); }

/* =========================================================================
   BENTO específicos
   ========================================================================= */
/* La tira de los 7 Activos del panel.
   En el escritorio caben los siete de una fila. En el móvil no: metidos a la
   fuerza salían siete columnas de cincuenta píxeles con los nombres cortados
   ("Ider", "Pos", "Ofe"). Ahí pasa a ser una tira que se arrastra con el
   dedo, con cada Activo lo bastante ancho para leerse entero. */
.tira-activos { display: grid; grid-template-columns: repeat(7, 1fr); gap: 14px; }
@media (max-width: 900px) {
  .tira-activos {
    display: flex; gap: 10px;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* El desplazamiento se para en cada tarjeta, no a mitad de una. */
    scroll-snap-type: x mandatory;
    /* Para que la primera y la última no queden pegadas al borde. */
    padding-bottom: 4px;
  }
  .tira-activos::-webkit-scrollbar { display: none; }
  .tira-activos > * { flex: 0 0 132px; scroll-snap-align: start; }
}

.asset-tile { display: flex; flex-direction: column; gap: 10px; cursor: pointer; }
.asset-tile .icon-wrap { width: 40px; height: 40px; border-radius: 12px; background: rgba(255,255,255,0.05); display: flex; align-items: center; justify-content: center; color: var(--text-secondary); }
.asset-tile.completado .icon-wrap { background: var(--accent-soft); color: var(--accent); }
.asset-tile.en_progreso .icon-wrap { background: var(--warning-soft); color: var(--warning); }
.asset-tile.bloqueado { opacity: 0.45; }
.asset-tile.bloqueado .icon-wrap { color: var(--text-muted); }

.phase-pill-row { display: flex; gap: 8px; flex-wrap: wrap; }
.phase-pill { padding: 8px 14px; border-radius: var(--radius-pill); font-size: 12.5px; font-weight: 700; border: 1px solid var(--border-subtle); color: var(--text-muted); background: rgba(255,255,255,0.02); }
.phase-pill.current { color: var(--accent); border-color: rgba(205,211,218,0.4); background: var(--accent-soft); box-shadow: 0 0 20px rgba(205,211,218,0.15); }
.phase-pill.done { color: var(--text-secondary); border-color: var(--border-glass); }

/* Kanban */
.kanban-board { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start; }
.kanban-col { background: rgba(255,255,255,0.02); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); width: 280px; flex-shrink: 0; padding: 12px; min-height: 120px; }
.kanban-col.drag-over { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft) inset; }
.kanban-col-header { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 12px; }
/* Faltaba: las tarjetas de una columna salían pegadas unas a otras. */
.kanban-cards { display: flex; flex-direction: column; gap: 10px; min-height: 60px; }
.kanban-col-title { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); }
.kanban-card { background: var(--bg-card); border: 1px solid var(--border-subtle); border-radius: 14px; padding: 12px; margin-bottom: 10px; cursor: grab; transition: all 0.15s var(--ease); }
.kanban-card:hover { border-color: var(--border-glass); transform: translateY(-1px); }
.kanban-card.dragging { opacity: 0.4; }
.kanban-card .title { font-size: 13.5px; font-weight: 600; margin-bottom: 8px; }

/* Chat */
.chat-layout { display: grid; grid-template-columns: 300px 1fr; gap: 0; border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); overflow: hidden; height: calc(100vh - 170px); min-height: 500px; }
.chat-list { border-right: 1px solid var(--border-subtle); overflow-y: auto; background: rgba(255,255,255,0.015); }
.chat-list-item { display: flex; gap: 10px; padding: 13px 14px; cursor: pointer; border-bottom: 1px solid var(--border-subtle); transition: background 0.15s var(--ease); }
.chat-list-item:hover { background: rgba(255,255,255,0.04); }
.chat-list-item.active { background: var(--accent-soft); }
.chat-list-item .meta { flex: 1; min-width: 0; }
.chat-list-item .name-row { display: flex; justify-content: space-between; align-items: center; gap: 6px; min-width: 0; }
.chat-list-item .name { font-size: 13.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.chat-list-item .time { flex-shrink: 0; }
.chat-list-item .preview { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.chat-list-item .time { font-size: 10.5px; color: var(--text-muted); }
.unread-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 8px rgba(255,107,107,0.5); flex-shrink: 0; }
.chat-window { display: flex; flex-direction: column; height: 100%; min-width: 0; }
.chat-window-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border-subtle); }
.chat-messages { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.msg-row { display: flex; gap: 10px; max-width: 72%; }
.msg-row.me { align-self: flex-end; flex-direction: row-reverse; }
.msg-bubble { padding: 10px 14px; border-radius: 16px; font-size: 13.5px; line-height: 1.45; background: var(--bg-card); border: 1px solid var(--border-subtle); }
.msg-row.me .msg-bubble { background: var(--accent); color: var(--accent-ink); border-color: transparent; border-bottom-right-radius: 4px; }
.msg-row:not(.me) .msg-bubble { border-bottom-left-radius: 4px; }
.msg-time { font-size: 10px; color: var(--text-muted); margin-top: 4px; }
.chat-input-row { display: flex; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--border-subtle); align-items: flex-end; }
.chat-input-row .textarea { min-height: 44px; max-height: 140px; }
.typing-indicator { font-size: 11.5px; color: var(--text-muted); padding: 0 20px 8px; font-style: italic; }

/* Selector de canal del chat del equipo. Cada uno entra a lo suyo —el
   Asesor a sus conversaciones, Mitxel y Lecny a las suyas— y desde aquí
   pasa a ver el resto. El número es lo que está sin leer en cada uno. */
.canal-filtro {
  display: flex; gap: 6px; margin-bottom: 14px;
  overflow-x: auto; scrollbar-width: none;
}
/* Los rótulos de la lista de conversaciones. En el móvil la lista pasa a
   ser una tira horizontal y estos se convertirían en columnas de texto
   apretado entre los avatares, así que ahí desaparecen. */
.chat-list-label {
  padding: 10px 14px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; color: var(--text-muted);
}
.canal-filtro::-webkit-scrollbar { display: none; }
.canal-chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle); background: transparent;
  color: var(--text-secondary); font-size: 12px; font-weight: 600;
  cursor: pointer; white-space: nowrap; font-family: var(--font-body);
  transition: all 0.15s var(--ease);
}
.canal-chip:hover { color: var(--text-primary); background: rgba(255,255,255,0.04); }
.canal-chip.active { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.canal-n {
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--danger); color: #fff; font-size: 10px; font-weight: 700;
}
.canal-chip.active .canal-n { background: rgba(0,0,0,0.28); color: inherit; }

/* El chat en el móvil.
   Las dos columnas (lista de 300 px + conversación) no caben en 375: la
   segunda se salía de la pantalla. Aquí la lista de canales pasa arriba,
   en horizontal, y la conversación ocupa todo el ancho debajo.
   La altura no se calcula contra 100vh porque en el móvil esa medida no
   incluye la barra del navegador y la caja de escribir se queda debajo del
   borde: se usa dvh, que sí se ajusta a lo que de verdad se ve. */
@media (max-width: 900px) {
  .chat-layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    height: calc(100dvh - 210px);
    min-height: 420px;
  }
  .chat-list {
    display: flex; border-right: 0;
    border-bottom: 1px solid var(--border-subtle);
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .chat-list::-webkit-scrollbar { display: none; }
  .chat-list-item {
    flex: 0 0 auto; max-width: 210px;
    border-bottom: 0; border-right: 1px solid var(--border-subtle);
  }
  .chat-list-item .preview { display: none; }
  .chat-list-label { display: none; }
  .msg-row { max-width: 88%; }
  .chat-messages { padding: 14px; }
  .chat-input-row { padding: 12px 14px; }
}

/* Rich text editor */
.rte-toolbar { display: flex; gap: 4px; padding: 8px; border: 1px solid var(--border-subtle); border-bottom: none; border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: rgba(255,255,255,0.02); }
.rte-toolbar button { width: 30px; height: 30px; border-radius: 8px; border: none; background: transparent; color: var(--text-secondary); cursor: pointer; font-weight: 700; font-size: 13px; }
.rte-toolbar button:hover { background: rgba(255,255,255,0.08); color: var(--text-primary); }
.rte-content { border: 1px solid var(--border-subtle); border-radius: 0 0 var(--radius-sm) var(--radius-sm); padding: 16px; min-height: 160px; font-size: 14px; line-height: 1.6; outline: none; }
.rte-content:focus { border-color: var(--accent); }
.rte-content p { margin: 0 0 10px; }
.rte-content h3 { margin: 0 0 8px; }
.rte-content ul, .rte-content ol { margin: 0 0 10px; padding-left: 20px; }

/* Pizarra de ideas (clon de Miro) */
.wb-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 10px; flex-wrap: wrap; }
.wb-toolbar-group { display: flex; align-items: center; gap: 6px; padding: 5px; background: rgba(255,255,255,0.03); border: 1px solid var(--border-subtle); border-radius: 12px; }
.wb-zoom-group { display: flex; align-items: center; gap: 4px; background: rgba(255,255,255,0.04); border: 1px solid var(--border-subtle); border-radius: 10px; padding: 3px; }
.wb-viewport { border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); overflow: auto; height: calc(100vh - 300px); min-height: 440px; background: #0d0d0d; cursor: default; }
.wb-zoom-sizer { position: relative; }
.wb-canvas { position: relative; width: 2200px; height: 1500px; transform-origin: 0 0; background-image: radial-gradient(rgba(255,255,255,0.07) 1.5px, transparent 1.5px); background-size: 24px 24px; cursor: grab; }
.wb-canvas:active { cursor: grabbing; }
.wb-arrows-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.wb-arrow-line { stroke: var(--accent); stroke-width: 2; opacity: 0.75; }
.wb-arrow-hit { stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }

/* Notas — arrastrables desde cualquier punto (ver whiteboard.js) */
.wb-note {
  position: absolute; border-radius: 14px; box-shadow: 0 8px 20px rgba(0,0,0,0.35); color: #06140c;
  overflow: hidden; transition: box-shadow 0.15s var(--ease), outline-color 0.15s var(--ease); cursor: grab;
  outline: 3px solid transparent; outline-offset: 2px;
}
.wb-note.dragging { box-shadow: 0 20px 45px rgba(0,0,0,0.55); z-index: 50; cursor: grabbing; }
.wb-note.connecting { outline-color: #fff; }
.wb-note-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 8px; background: rgba(0,0,0,0.1); }
.wb-color-dot { width: 13px; height: 13px; border-radius: 50%; border: 1.5px solid rgba(0,0,0,0.2); cursor: pointer; padding: 0; flex-shrink: 0; }
.wb-color-dot.active { border-color: #06140c; box-shadow: 0 0 0 1.5px rgba(255,255,255,0.5); }
.wb-note-del { width: 19px; height: 19px; border-radius: 50%; border: none; background: rgba(0,0,0,0.14); color: #06140c; display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }
.wb-note-text { padding: 4px 12px 14px; font-size: 13px; line-height: 1.45; min-height: 64px; outline: none; font-weight: 600; white-space: pre-wrap; cursor: text; }
.wb-resize-handle { position: absolute; right: 2px; bottom: 2px; width: 16px; height: 16px; cursor: nwse-resize; z-index: 2; }
.wb-resize-handle::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 8px; height: 8px; border-right: 2px solid rgba(0,0,0,0.35); border-bottom: 2px solid rgba(0,0,0,0.35); }

/* Secciones (frames) — agrupan notas visualmente, arrastrables en bloque */
.wb-frame { position: absolute; border: 1.5px dashed var(--border-glass); border-radius: 12px; background: rgba(255,255,255,0.015); cursor: grab; }
.wb-frame.dragging { cursor: grabbing; border-color: var(--accent); }
.wb-frame-head { position: absolute; top: -30px; left: -1.5px; display: flex; align-items: center; gap: 6px; padding: 4px 8px; border-radius: 8px 8px 0 0; background: rgba(255,255,255,0.06); }
.wb-frame-label { font-size: 12px; font-weight: 700; color: var(--text-primary); outline: none; min-width: 40px; cursor: text; }
.wb-frame .wb-note-del { background: rgba(255,255,255,0.1); color: var(--text-secondary); }
.wb-frame .wb-resize-handle::after { border-color: var(--border-glass); }

/* Texto libre, sin fondo — como el bloque de texto de Miro */
.wb-text { position: absolute; display: flex; align-items: flex-start; gap: 6px; max-width: 420px; cursor: grab; padding: 4px; margin: -4px; }
.wb-text.dragging { cursor: grabbing; }
.wb-text-content { font-weight: 700; color: var(--text-primary); outline: none; white-space: pre-wrap; min-width: 30px; cursor: text; }
.wb-text .wb-note-del { opacity: 0; transition: opacity 0.15s var(--ease); background: rgba(255,255,255,0.1); color: var(--text-secondary); margin-top: 3px; }
.wb-text:hover .wb-note-del { opacity: 1; }

/* Arquitectura™ — sala 3D navegable (Three.js) con asistentes IA */
.aula3d-wrap { border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); background: #0a0a0a; padding: 0; position: relative; overflow: hidden; }
.aula3d-legend { position: absolute; top: 18px; left: 22px; z-index: 2; max-width: 320px; pointer-events: none; }
.aula3d-canvas-mount { width: 100%; height: min(72vh, 680px); min-height: 460px; }
.aula3d-canvas-mount canvas { display: block; width: 100%; height: 100%; cursor: grab; }

/* Calendar */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-dow { text-align: center; font-size: 10.5px; color: var(--text-muted); font-weight: 700; text-transform: uppercase; padding-bottom: 6px; }
.cal-day { aspect-ratio: 1; border-radius: 10px; background: rgba(255,255,255,0.02); border: 1px solid var(--border-subtle); padding: 6px; font-size: 11.5px; color: var(--text-secondary); position: relative; }
.cal-day.today { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.cal-day.other-month { opacity: 0.3; }
.cal-day .evt-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); position: absolute; bottom: 6px; left: 6px; }

/* Reproductor de lecciones */
.video-frame {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #000; border-radius: var(--radius-md); overflow: hidden;
  border: 1px solid var(--border-subtle);
}
.video-frame video, .video-frame iframe {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; display: block; object-fit: contain;
}

/* Rejilla de acceso: alumnos × módulos, una casilla por cruce. */
.acceso-tabla th { vertical-align: top; padding-top: 12px; padding-bottom: 12px; }
.acceso-celda {
  width: 62px; min-height: 40px; padding: 6px 4px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  margin: 0 auto; border-radius: 10px; font-family: inherit;
  background: rgba(255,255,255,0.03); border: 1px solid var(--border-subtle);
  color: var(--text-muted); transition: all 0.15s var(--ease);
}
.acceso-celda:hover:not(:disabled) { border-color: var(--border-glass); background: rgba(255,255,255,0.07); color: var(--text-secondary); }
.acceso-celda.abierta {
  background: linear-gradient(180deg, rgba(205,211,218,0.2), rgba(205,211,218,0.07));
  border-color: rgba(205,211,218,0.45); color: var(--accent-bright);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.18);
}
.acceso-celda.auto { cursor: default; opacity: 0.75; }
.acceso-sub { font-size: 9.5px; font-weight: 600; letter-spacing: 0.02em; opacity: 0.85; }

/* Tarjeta de módulo del Campus: cabecera en degradado con el nombre
   grande y el progreso, y debajo sus lecciones. La cabecera es lo que
   hace que un módulo se lea como una unidad y no como una lista más. */
.modulo-card {
  border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--border-subtle);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.modulo-head {
  padding: 28px 28px 24px;
  background:
    radial-gradient(760px 260px at 2% -24%, rgba(205,211,218,0.34), transparent 60%),
    linear-gradient(156deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.07) 38%, rgba(255,255,255,0.018) 100%);
  border-bottom: 1px solid var(--border-glass);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
  position: relative;
}
.modulo-head::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.85), transparent);
}
.modulo-num { font-size: 10.5px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--text-muted); }
.modulo-titulo {
  font-family: var(--font-display); font-size: 32px; font-weight: 700;
  letter-spacing: -0.035em; line-height: 1.06; margin-top: 10px;
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 45%, #9aa5b1 100%);
  background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.modulo-body { padding: 22px 28px 28px; background: rgba(0,0,0,0.22); }
/* El módulo en el que está: se ve desde el otro lado de la sala. */
.modulo-card.en-curso { border-color: rgba(205,211,218,0.55); box-shadow: 0 0 64px rgba(205,211,218,0.18), var(--shadow-card); }
.modulo-card.hecho .modulo-head {
  background:
    radial-gradient(700px 240px at 4% -20%, rgba(205,211,218,0.28), transparent 62%),
    linear-gradient(158deg, rgba(205,211,218,0.16), rgba(255,255,255,0.02));
}
.modulo-card.locked { opacity: 0.45; }
.modulo-card.locked .modulo-head { background: linear-gradient(160deg, rgba(255,255,255,0.03), transparent); }

/* La ruta del programa — dónde está el alumno y qué le queda */
.ruta { display: flex; gap: 0; flex-wrap: wrap; }
/* Diez etapas — IPP, arranque, los 7 Activos y el cierre — tienen que
   caber en una sola fila en escritorio: partida en dos, la línea que las
   une deja de leerse como un camino. */
.ruta-paso {
  flex: 1 1 74px; min-width: 74px; text-align: center;
  padding: 0 2px 4px; position: relative;
}
/* La línea que une un paso con el siguiente, por detrás de los puntos. */
.ruta-paso::before {
  content: ""; position: absolute; top: 17px; left: -50%; width: 100%; height: 2px;
  background: var(--border-subtle); z-index: 0;
}
.ruta-paso:first-child::before { display: none; }
.ruta-paso.done::before, .ruta-paso.now::before { background: var(--accent); }
/* Disponible pero no es donde está: se intuye sin competir con el "ahora". */
.ruta-paso.abierto .ruta-punto { border-color: rgba(205,211,218,0.45); color: var(--text-secondary); }
.ruta-paso.abierto .ruta-nombre { color: var(--text-secondary); }
.ruta-punto {
  position: relative; z-index: 1; width: 36px; height: 36px; margin: 0 auto 10px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 2px solid var(--border-subtle); color: var(--text-muted);
  transition: all 0.2s var(--ease);
}
.ruta-paso.done .ruta-punto { border-color: var(--accent); color: var(--accent-ink); }
.ruta-paso.now .ruta-punto {
  border-color: var(--accent-bright); color: var(--accent-bright);
  box-shadow: 0 0 0 5px rgba(205,211,218,0.14), 0 0 26px rgba(205,211,218,0.5);
  background: linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.03)), var(--bg-card);
}
.ruta-paso.done .ruta-punto {
  background: linear-gradient(180deg, var(--accent-bright), var(--accent));
  box-shadow: 0 0 16px rgba(205,211,218,0.4), inset 0 1px 0 rgba(255,255,255,0.9);
}
.ruta-nombre { font-size: 11.5px; font-weight: 700; line-height: 1.25; color: var(--text-muted); }
.ruta-paso.done .ruta-nombre { color: var(--text-secondary); }
.ruta-paso.now .ruta-nombre { color: var(--text-primary); }
.ruta-sub { font-size: 10px; color: var(--text-muted); margin-top: 3px; }
@media (max-width: 640px) {
  .ruta-paso { flex: 1 1 76px; min-width: 76px; }
  .ruta-sub { display: none; }
}

/* Tick de "lección vista" */
.lesson-tick {
  width: 22px; height: 22px; flex-shrink: 0; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: transparent; color: var(--text-muted);
  border: 1.5px solid var(--border-glass);
  transition: all 0.15s var(--ease);
}
.lesson-tick:hover:not(.disabled) { border-color: var(--accent); color: var(--accent); }
.lesson-tick.checked { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
/* Apagado hasta que el vídeo esté visto entero. */
.lesson-tick.disabled { opacity: 0.3; cursor: not-allowed; }

/* IPP — opciones de respuesta */
.ipp-option {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 12px 14px; text-align: left; cursor: pointer;
  background: rgba(255,255,255,0.02); color: var(--text-secondary);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
  font-family: inherit; transition: all 0.15s var(--ease);
}
.ipp-option:hover { background: rgba(255,255,255,0.05); border-color: var(--border-glass); }
.ipp-option.selected { background: var(--accent-soft); border-color: var(--accent); color: var(--text-primary); }
.ipp-option-dot {
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0; margin-top: 2px;
  border: 1.5px solid var(--text-muted); transition: all 0.15s var(--ease);
}
.ipp-option.selected .ipp-option-dot { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 3px var(--bg-card); }

/* Community */
.community-post { display: flex; gap: 12px; }
.community-post .body { background: var(--bg-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 14px 16px; flex: 1; }

/* Login helpers, community, misc responsive text */
.empty-state { text-align: center; padding: 50px 20px; color: var(--text-muted); }
.empty-state svg { width: 40px; height: 40px; margin-bottom: 12px; opacity: 0.5; }

.divider { height: 1px; background: var(--border-subtle); border: none; margin: 16px 0; }

.lucide { display: inline-flex; }
.lucide svg { display: block; }

@media print { body { display: none; } }
