@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  /* ---- Bloque 6-8: paleta institucional SaaS B2B (2026-09-11) ----
     --blue/--blue-deep se REDEFINEN aqui (mismos nombres de variable que
     ya usaba toda la app) para que el cambio de marca se propague solo,
     sin tocar cada regla que ya consumia var(--blue)/var(--blue-deep). */
  /* ---- UI/UX premium (2026-09-14) -- tokens ajustados sobre el mismo
     :root, no un segundo sistema (ver instruccion, Seccion 6). --blue/
     --blue-deep siguen siendo los nombres que consume TODA la app --
     redefinirlos aqui basta para propagar la paleta sin tocar cada regla. */
  --blue: #2EA3FF;        /* --accent del spec: foco, links, charts */
  --blue-alt: #47A8FF;
  --blue-deep: var(--sc-primary);   /* --primary del spec: botones, sidebar */
  --blue-soft: var(--sc-info-soft);
  --green: #4f9d72;
  --green-deep: #366e50;
  --green-soft: #e9f4ec;
  --ink: var(--sc-text);
  --gold: #d1a441;
  --muted: var(--sc-text-muted);
  --border: var(--sc-border);

  --surface-app: var(--sc-surface-subtle);
  --surface-app-2: #eaf1fa;
  --surface-card: #ffffff;
  --gray-50: #f6f8fb;
  --gray-100: #eef2f7;
  --gray-200: #e2e8f0;

  --radius-control: var(--sc-radius-md); /* botones/inputs */
  --radius-card: var(--sc-radius-lg);
  --sidebar-w: 220px;
  --topbar-h: 60px;
  --tabbar-h: 60px;

  /* Estados semanticos, centralizados -- antes cada pantalla elegia su
     propio verde/ambar/rojo (.alert-ok, .btn-red, etc). Se mantienen esas
     clases (compatibilidad) pero ahora TODAS leen de aqui. */
  --state-success: var(--sc-success);
  --state-success-soft: var(--sc-success-soft);
  --state-warning: var(--sc-warning);
  --state-warning-soft: var(--sc-warning-soft);
  --state-danger: var(--sc-danger);
  --state-danger-soft: var(--sc-danger-soft);
  --state-info: var(--sc-info);
  --state-info-soft: var(--sc-info-soft);

  /* Foco -- un unico anillo de foco reusado por toda la app. */
  --focus-ring: 0 0 0 3px rgba(46, 163, 255, 0.35);

  /* Sistema unico de radio y sombra — antes cada tarjeta tenia su propio
     valor (16/20/24px), lo que el ojo percibe como inconsistencia. */
  --radius: var(--sc-radius-lg);
  --radius-sm: var(--sc-radius-sm);
  --radius-pill: var(--sc-radius-pill);
  --shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 12px 28px -14px rgba(13, 42, 82, 0.16);
  --shadow-sm: var(--sc-shadow-sm);
  --shadow-lift: var(--sc-shadow-md);

  /* Espaciado base de 8px. */
  --sp-1: 8px;
  --sp-2: 16px;
  --sp-3: 24px;
  --sp-4: 32px;

  /* Movimiento -- tiempos y curvas unicos para toda la app (Bloque 6-8 §3). */
  --dur-micro: 140ms;
  --dur-component: 200ms;
  --dur-page: 280ms;
  --ease-standard: cubic-bezier(0.2, 0.7, 0.3, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ==== RC-2 DESIGN SYSTEM -- tokens canonicos (--sc-*). Ver
     docs/SMART_CAMPUS_DESIGN_SYSTEM_SPEC.md. Los nombres legacy de arriba
     (--blue, --radius, --shadow-sm, --sp-*) siguen existiendo y apuntan a
     estos valores: no es un segundo sistema, es el mismo con nombres
     canonicos. ==== */
  --sc-primary: #0B4F8A;
  --sc-primary-hover: #083E6C;
  --sc-secondary: #2EA3FF;
  --sc-text: #0F2740;
  --sc-text-muted: #5B6B7C;
  --sc-border: rgba(15, 39, 64, 0.12);
  --sc-surface: #ffffff;
  --sc-surface-subtle: #F4F7FB;
  --sc-success: #1a7f4b;
  --sc-success-soft: #e7f7ee;
  --sc-warning: #b45309;
  --sc-warning-soft: #fffbeb;
  --sc-danger: #c62828;
  --sc-danger-soft: #fef2f2;
  --sc-info: #0B4F8A;
  --sc-info-soft: #e9f6ff;

  --sc-space-1: 4px;
  --sc-space-2: 8px;
  --sc-space-3: 12px;
  --sc-space-4: 16px;
  --sc-space-5: 24px;
  --sc-space-6: 32px;

  --sc-radius-sm: 8px;
  --sc-radius-md: 12px;
  --sc-radius-lg: 16px;
  --sc-radius-pill: 999px;

  --sc-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 10px -4px rgba(13, 42, 82, 0.10);
  --sc-shadow-md: 0 1px 2px rgba(15, 23, 42, 0.05), 0 20px 40px -16px rgba(0, 42, 82, 0.22);

  --sc-fs-h1: 24px;
  --sc-lh-h1: 32px;
  --sc-fs-h2: 18px;
  --sc-lh-h2: 26px;
  --sc-fs-card: 15px;
  --sc-fs-body: 14px;
  --sc-fs-small: 12.5px;
  --sc-control-h: 44px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", "Segoe UI", ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(1200px 480px at 12% -10%, rgba(59, 180, 255, 0.10), transparent 60%),
    radial-gradient(900px 420px at 100% 0%, rgba(0, 42, 82, 0.06), transparent 55%),
    var(--surface-app);
  color: var(--ink);
  min-height: 100vh;
  letter-spacing: -0.006em;
}

a { color: inherit; text-decoration: none; }

/* ---------- Header ---------- */
header.topbar {
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 12px var(--sp-3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
}

header.topbar img.logo { height: clamp(40px, 8vw, 56px); width: auto; max-width: 100%; object-fit: contain; display: block; }
/* Modo vista de celular: no alcanza el ancho para un logo grande +
   controles lado a lado sin encimarse (medido: logo 132px centrado +
   controles 166px a la derecha se pisan en 375px) -- se apilan en dos
   filas, cada una centrada, en vez de compartir una sola fila angosta. */
@media (max-width: 640px) {
  header.topbar { flex-direction: column; height: auto; padding: var(--sp-2) var(--sp-3); }
  header.topbar img.logo { height: 48px; margin: 0 auto; }
}

nav.tabs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

nav.tabs a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: transparent;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--muted);
  transition: background-color .15s ease, color .15s ease;
}

nav.tabs a:hover { background: var(--blue-soft); color: var(--blue-deep); }

/* Segunda fila: herramientas de personal, visualmente separada de la nav
   publica/comercial para que no se lean como "una lista de 11 funciones". */
nav.tabs-staff {
  background: var(--blue-deep);
  padding: 8px var(--sp-3);
  gap: 4px;
  /* No sticky: un top fijo en px no puede coincidir de forma confiable con
     la altura real del header (varia con el wrap del logo/nav), y dos
     barras sticky apiladas con un offset equivocado se solapan al hacer
     scroll. Una barra secundaria que se desplaza con la pagina es
     suficiente para una sub-nav de herramientas. */
}
nav.tabs-staff a {
  height: 30px;
  padding: 0 14px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.75);
}
nav.tabs-staff a:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
nav.tabs-staff a.active { background: rgba(255, 255, 255, 0.18); color: #fff; font-weight: 600; }
.tabs-staff-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: rgba(255, 255, 255, 0.5);
  padding-right: 6px;
  white-space: nowrap;
}

/* :not(.tabs-staff) — sin esto, esta regla y nav.tabs-staff a.active tienen
   la misma especificidad y esta gana por venir despues en el archivo,
   dejando la pestana activa invisible sobre el fondo oscuro de personal
   (mismo azul que el fondo de la barra). */
nav.tabs:not(.tabs-staff) a.active {
  background: var(--blue-deep);
  color: #fff;
  font-weight: 600;
}

.status-dot { font-size: 12px; margin-left: 4px; cursor: default; }

/* RC-2: "Salir"/"Volver" son enlaces de navegacion, no CTAs -- variante Ghost
   del sistema unico de botones (misma gramatica: radio md, sin pildora). */
a.btn-logout {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px;
  margin-left: 4px; border-radius: var(--sc-radius-md); background: transparent;
  border: 1px solid var(--sc-border); color: var(--sc-primary); font-size: 13px; font-weight: 600;
}
a.btn-logout:hover { background: var(--sc-info-soft); }

/* ---------- Pantalla de bienvenida (entrada al sitio) ---------- */
.welcome-screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  text-align: center;
  padding: var(--sp-3);
  background:
    radial-gradient(1100px 520px at 15% -8%, rgba(59, 180, 255, 0.14), transparent 60%),
    radial-gradient(900px 420px at 100% 100%, rgba(0, 42, 82, 0.08), transparent 55%),
    var(--surface-app);
}
.welcome-logo { height: 96px; max-width: 80vw; }
.welcome-title {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0;
}
.welcome-btn { padding: 0 40px; font-size: 15px; }

main.content { max-width: 1080px; margin: 0 auto; padding: var(--sp-4) var(--sp-3) 72px; }

.demo-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 12px;
  /* RC-2.1 (F-05): sin alto fijo -- el texto puede envolver a 2 lineas (carnet a
     375px y a 1280px) sin recortarse; min-height conserva la forma de una linea. */
  min-height: 26px;
  padding: 4px var(--sp-2);
  line-height: 1.4;
  text-align: center;
  max-width: 100%;
  overflow-wrap: anywhere;
  border-radius: 14px;
  background: var(--blue-soft);
  color: var(--blue-deep);
  border: 1px solid rgba(47, 143, 240, 0.22);
  font-weight: 500;
}

.center { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--sp-1); }


.subtitle { color: var(--muted); max-width: 520px; margin: 0; font-size: 15px; line-height: 1.55; }

/* ---------- Tarjetas: un unico radio + sombra en toda la app ---------- */
/* RC-2: familia de superficies -- misma base (radio lg, borde, sombra sm) */
.card, .stat, .sc-kpi, .solution-card, .hub-card, .sc-card-list-item, .sc-auth-card {
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius-lg);
  box-shadow: var(--sc-shadow-sm);
}
.card { padding: var(--sp-3); }
.card-label { font-size: var(--sc-fs-card); }

/* ==== RC-2: CONTROL BASE UNICO (input/select/textarea) ==== */
.select, form.stack select,
form.stack input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):not([type="submit"]):not([type="button"]),
input.sc-input, textarea.sc-input {
  height: var(--sc-control-h); width: 100%; padding: 0 14px; font-size: var(--sc-fs-body); font-weight: 500;
  font-family: inherit; color: var(--sc-text); background: var(--sc-surface);
  border: 1px solid var(--sc-border); border-radius: var(--sc-radius-md);
  transition: border-color var(--dur-micro) ease, box-shadow var(--dur-micro) ease;
}
.select { width: auto; min-width: 160px; }
form.stack textarea {
  min-height: 96px; padding: 10px 14px; font-size: var(--sc-fs-body); font-family: inherit; color: var(--sc-text);
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius-md); resize: vertical; width: 100%;
}
.select:hover, form.stack input:hover, form.stack textarea:hover { border-color: rgba(15, 39, 64, 0.28); }
.select:focus-visible, form.stack input:focus-visible, form.stack select:focus-visible, form.stack textarea:focus-visible {
  outline: none; border-color: var(--sc-secondary); box-shadow: var(--focus-ring);
}
.select:disabled, form.stack input:disabled, form.stack textarea:disabled, form.stack select:disabled {
  background: var(--sc-surface-subtle); color: var(--sc-text-muted); cursor: not-allowed;
}
.is-invalid, [aria-invalid="true"] { border-color: var(--sc-danger) !important; }
.sc-help { font-size: var(--sc-fs-small); color: var(--sc-text-muted); margin: 2px 0 0; }
.sc-field-error { font-size: var(--sc-fs-small); color: var(--sc-danger); font-weight: 600; margin: 2px 0 0; }
form.stack input[type="checkbox"], form.stack input[type="radio"] { width: 18px; height: 18px; accent-color: var(--sc-primary); flex-shrink: 0; }

/* ==== RC-2: SISTEMA UNICO DE BOTONES ====
   Canonico: .btn + variante. .sc-btn* y los nombres legacy (.btn-soft,
   .btn-outline, .btn-green/-amber/-red, .icon-btn) son ALIAS del mismo
   aspecto (selectores agrupados), no un segundo sistema. Pildora NO es
   forma de boton (reservada a badges/chips/estados). ==== */
.btn, .sc-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: var(--sc-control-h); padding: 0 20px; border: 1px solid transparent;
  border-radius: var(--sc-radius-md); font-size: var(--sc-fs-body); font-family: inherit; font-weight: 600;
  line-height: 1; cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color var(--dur-micro) ease, border-color var(--dur-micro) ease, transform .1s ease;
}
.btn:active, .sc-btn:active { transform: scale(0.98); }

/* Primary */
.btn-primary, .sc-btn-primary { background: var(--sc-primary); color: #fff; }
.btn-primary:hover, .sc-btn-primary:hover { background: var(--sc-primary-hover); }
/* Secondary (alias: btn-soft, btn-outline, sc-btn-ghost) */
.btn-secondary, .btn-soft, .btn-outline, .sc-btn-ghost {
  background: var(--sc-surface); color: var(--sc-primary); border-color: var(--sc-border);
}
.btn-secondary:hover, .btn-soft:hover, .btn-outline:hover, .sc-btn-ghost:hover {
  background: var(--sc-info-soft); border-color: rgba(11, 79, 138, 0.28);
}
/* Ghost (baja jerarquia, texto) */
.btn-ghost, a.btn-back-hub { background: transparent; color: var(--sc-text-muted); }
.btn-ghost:hover, a.btn-back-hub:hover { background: var(--sc-info-soft); color: var(--sc-primary); }
/* Destructive: contorno, no compite con la accion primaria */
.btn-danger { background: var(--sc-surface); color: var(--sc-danger); border-color: var(--sc-border); }
.btn-danger:hover { background: var(--sc-danger-soft); border-color: rgba(198, 40, 40, 0.45); }
/* Estado solido: SOLO marcado de asistencia (Presente/Tardanza/Ausente) */
.btn-success, .btn-green { background: var(--sc-success); color: #fff; }
.btn-success:hover, .btn-green:hover { background: #146339; }
.btn-warning, .btn-amber { background: var(--sc-warning); color: #fff; }
.btn-warning:hover, .btn-amber:hover { background: #92400e; }
.btn-critical, .btn-red { background: var(--sc-danger); color: #fff; }
.btn-critical:hover, .btn-red:hover { background: #a61f1f; }
/* Compacto (alias icon-btn): UN solo tamano secundario, 36px; 44px en movil */
.btn-sm, .icon-btn { height: 36px; padding: 0 14px; font-size: 13px; flex-shrink: 0; }
@media (max-width: 640px) { .btn-sm, .icon-btn { height: 44px; } }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-2); }
@media (max-width: 640px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-2-cols { grid-template-columns: 1fr !important; }
}

.stat, .sc-kpi { padding: var(--sp-2); text-align: center; }
.stat .value, .sc-kpi .value { font-size: 27px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.stat .label, .sc-kpi .label { font-size: 12.5px; color: var(--muted); margin-top: 3px; font-weight: 500; }
/* Capa 2 Visual: tercera linea opcional de contexto (etiqueta + valor +
   contexto) -- mismo componente .stat/.sc-kpi, nunca un segundo sistema
   paralelo. Solo se usa donde de verdad hay un dato de contexto real que
   mostrar (nunca relleno). */
.sc-kpi .context { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Capa 2 Visual: tarjeta "Requiere atencion" -- mismo tratamiento visual
   que el banner "Falta pasar lista" de profesor.php (border-left +
   fondo tintado de --state-warning), formalizado como clase reusable en
   vez de estilos inline repetidos. profesor.php NO se toca (ver
   instruccion NO TOCAR) -- esta clase es nueva, solo la consume
   admin.php. */
.sc-attn-card {
  border-left: 3px solid var(--state-warning);
  background: var(--state-warning-soft);
}
.sc-attn-card .card-label { color: var(--state-warning); }
.sc-attn-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: 7px 0; border-top: 1px solid rgba(180, 83, 9, 0.14); }
.sc-attn-row:first-of-type { border-top: none; }

/* El radio/sombra/recorte vive en el envoltorio (.table-wrap), no en la
   tabla — si overflow:hidden estuviera en table.data, una tabla mas ancha
   que la pantalla se recortaria en vez de poder desplazarse en movil. */
.table-wrap {
  border-radius: var(--radius);
  overflow-x: auto;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border);
}
.table-wrap table.data { box-shadow: none; border: none; border-radius: 0; }
table.data {
  width: 100%; border-collapse: collapse; background: #fff;
  box-shadow: var(--shadow-sm); border: 1px solid var(--border); border-radius: var(--radius);
}
/* Solo las tablas con varias columnas (Administracion, Red de Sedes,
   Auditoria) necesitan un ancho minimo que fuerce scroll horizontal en
   movil — una tabla simple de 3 columnas (boleta) cabe sin forzarlo. */
table.data.wide { min-width: 560px; }
table.data th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; font-weight: 600;
  color: var(--sc-text-muted); background: var(--sc-surface-subtle); padding: 12px 16px;
}
table.data td { padding: 12px 16px; border-top: 1px solid var(--border); font-size: 14px; }
table.data tbody tr:hover { background: rgba(47, 143, 240, 0.04); }

.badge-type { padding: 2px 10px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; }
.badge-privado { background: var(--sc-info-soft); color: var(--sc-info); }
.badge-publico { background: var(--sc-success-soft); color: var(--sc-success); }

.roster-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--border);
  flex-wrap: wrap; row-gap: 8px;
}
.roster-row:first-child { border-top: none; }
.roster-name { font-size: 14px; font-weight: 500; }
@media (max-width: 400px) {
  /* Nombre + 3 botones de estado ya no caben en una sola fila en un
     telefono angosto (encontrado en 375px al revisar Asistencia,
     Bloque 6-8) -- se envuelven en vez de desbordar la pagina. */
  .mark-buttons { width: 100%; justify-content: flex-start; }
}
.roster-id { font-family: ui-monospace, monospace; font-size: 11px; color: var(--muted); }
/* Update 2, punto 2.1: telefono de contacto de emergencia en la fila de
   asistencia -- vive en el bloque IZQUIERDO (nombre/id), nunca dentro de
   .mark-buttons, para que su area de toque jamas compita con los 3
   botones de estado (Presente/Tardanza/Ausente siguen siendo los
   unicos elementos ahi, cada uno >=44px sin cambios). */
.sc-emergency-phone {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 3px;
  font-size: 12px; font-weight: 600; color: var(--blue-deep); text-decoration: none;
  min-height: 28px; padding: 2px 0;
}
.sc-emergency-phone svg { width: 14px; height: 14px; flex-shrink: 0; }
.sc-emergency-phone:hover { text-decoration: underline; }

.carnet {
  width: 320px; max-width: 100%; border-radius: 20px; overflow: hidden; background: #fff;
  box-shadow: var(--shadow); border: 1px solid var(--border);
}
.carnet .head {
  background: linear-gradient(135deg, var(--blue), var(--blue-deep));
  color: #fff; padding: var(--sp-2) 20px;
}
.carnet .body { padding: 20px; display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }

footer.site {
  text-align: center; font-size: 12px; color: var(--muted);
  padding: var(--sp-3); margin-top: var(--sp-2);
}

/* RC-2: alertas unificadas -- borde izquierdo semantico + fondo soft; tokens
   de estado, no colores sueltos. El texto siempre comunica el estado. */
.alert {
  border-radius: var(--sc-radius-md); padding: 12px var(--sp-3); text-align: left; font-size: var(--sc-fs-body);
  line-height: 1.55; border: 1px solid transparent; border-left-width: 4px; font-weight: 500;
}
.alert-ok { background: var(--sc-success-soft); color: var(--sc-success); border-color: rgba(26, 127, 75, 0.25); }
.alert-warn { background: var(--sc-warning-soft); color: var(--sc-warning); border-color: rgba(180, 83, 9, 0.28); }
.alert-err { background: var(--sc-danger-soft); color: var(--sc-danger); border-color: rgba(198, 40, 40, 0.28); }
.alert-info { background: var(--sc-info-soft); color: var(--sc-info); border-color: rgba(11, 79, 138, 0.25); }

form.stack { display: flex; flex-direction: column; gap: var(--sp-1); max-width: 320px; margin: 0 auto; }
/* width:100% (control base, arriba) evita que un <input> desborde .field-row
   en movil (encontrado en 375px, Bloque 6-8). */
form.stack label { font-size: 13px; font-weight: 500; color: var(--sc-text); margin-top: 4px; }

/* ---------- Sesion de personal (linea bajo el badge de demo) ---------- */
.staff-session { font-size: 12px; color: var(--muted); }
.staff-session a { color: var(--blue-deep); font-weight: 500; }

/* ---------- Tarjeta de formulario centrada (Avisos, Administracion) ---------- */
.form-card { max-width: 560px; margin: 20px auto; }
.form-card form.stack { max-width: 100%; }

/* ---------- Lista vertical de tarjetas (avisos publicados) ---------- */
.stack-list { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: var(--sp-2); }
.stack-list .empty { text-align: center; }

.list-item { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-2); }
.list-item .body p { margin: 6px 0 0; font-size: 14px; color: var(--ink); }
.list-item .meta { font-size: 11px; margin-top: 8px; }
.icon-btn { font-size: 12px; padding: 4px 12px; flex-shrink: 0; }

/* ---------- Fila de dos campos lado a lado (Administracion) ---------- */
.field-row { display: flex; gap: var(--sp-2); }
/* min-width:0 -- un item flex nunca se encoge mas alla del ancho
   intrinseco de su contenido a menos que se le indique explicitamente;
   sin esto, un <input> ancho dentro de esta columna fuerza el
   desbordamiento horizontal completo de la pagina en movil. */
.field-row > div { flex: 1; min-width: 0; }
.field-row > div.grow-2 { flex: 2; }
@media (max-width: 480px) {
  /* Codigo/Nombre y Ciudad/Tipo lado a lado ya no caben con comodidad
     en un telefono angosto -- se apilan, cada input recupera su ancho
     completo (ya no depende de min-width:0 para no desbordar). */
  .field-row { flex-direction: column; }
}

/* ---------- Encabezado de tarjeta con accion a la derecha ---------- */
.card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--sp-2); }
.card-head .title-sm { font-weight: 600; margin: 0; }

/* ---------- Fila de selects (institucion/persona), reusada en varias vistas ---------- */
.selector-row { display: flex; gap: var(--sp-2); justify-content: center; margin: var(--sp-2) 0 var(--sp-3); flex-wrap: wrap; }

/* ---------- Variante ancha del carnet (boleta de notas) ---------- */
.carnet-wide { width: 420px; max-width: 100%; margin: 0 auto; }
.carnet-wide .head p.eyebrow { font-size: 11px; text-transform: uppercase; opacity: .7; margin: 0; }
.carnet-wide .head p.title-inline { font-weight: 600; margin: 2px 0 0; }
.carnet-wide .body { align-items: stretch; }
.report-summary { display: flex; justify-content: space-between; align-items: center; }
.report-summary .name { font-weight: 600; margin: 0; }
.report-summary .sub { font-size: 12px; color: var(--muted); margin: 2px 0 0; }
.stat-inline { padding: 8px 14px; }
.stat-inline .value { font-size: 18px; }
.text-right { text-align: right; }

/* ---------- Alertas centradas de ancho moderado (formularios de admin) ---------- */
.alert-narrow { max-width: 520px; margin: var(--sp-2) auto; }

/* ---------- Utilidades varias reusadas en Administracion ---------- */
.table-720 { max-width: 720px; margin: 0 auto; }
.inline-form { display: inline; }
.mono-cell { font-family: ui-monospace, monospace; font-size: 12px; }
.center-note { text-align: center; margin-top: var(--sp-2); font-size: 12px; }
.card-label { font-weight: 600; margin: 0 0 var(--sp-2); }

/* ---------- Carnet clasico (identidad digital) ---------- */
.carnet-wrap { display: flex; justify-content: center; }
.carnet .head p.eyebrow { font-size: 11px; text-transform: uppercase; opacity: .7; margin: 0; }
.carnet .head p.title-inline { font-weight: 600; margin: 2px 0 0; }
.carnet-info { text-align: center; }
.carnet-info .name { font-weight: 600; margin: 0; }
.carnet-info .sub { font-size: 13px; color: var(--muted); margin: 2px 0; }
.carnet-info .id { font-family: ui-monospace, monospace; font-size: 11px; color: var(--muted); margin: 0; }

/* ---------- Avatar/emblema placeholder temporal (Bloque 3 -- foto y
   escudo reales llegan en Bloque 4/5, ver PLAN) ---------- */
.avatar-circle {
  width: 72px; height: 72px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; font-size: 24px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, var(--blue), var(--blue-deep)); flex-shrink: 0;
}
.emblem-badge {
  width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center;
  justify-content: center; font-size: 16px; font-weight: 700; color: var(--blue-deep);
  background: var(--blue-soft); border: 1px solid rgba(47, 143, 240, 0.25); flex-shrink: 0;
}
.badge-phase-next {
  display: inline-flex; font-size: 11px; font-weight: 600; padding: 3px 10px;
  border-radius: var(--radius-pill); background: #f1f1ef; color: var(--muted);
}

/* ---------- Utilidades de ancho + tarjeta "flush" con barra de herramientas ---------- */
.max-w-520 { max-width: 520px; margin-left: auto; margin-right: auto; }
.card-flush { padding: 0; }
.card-toolbar {
  display: flex; justify-content: space-between; align-items: center;
  padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border);
}
.card-toolbar strong { font-size: 14px; }
/* LOTE P2 (P2-02): con un código no-sistema activo (ej. "Justificada")
   hay un 4o boton en la fila -- en 375px ya no cabe junto a los 3 de
   siempre sin recortarse. flex-wrap deja que el/los codigo(s) extra
   caigan a una segunda fila en vez de desbordar la pagina; los 3
   botones de sistema (Presente/Tardanza/Ausente) siguen sin cambios de
   tamaño ni de POST, solo cambia donde caen visualmente. */
.mark-buttons { display: flex; flex-wrap: wrap; gap: var(--sp-1); row-gap: 8px; }

/* ==========================================================================
   Rediseno premium 2026-09-10 — Bienvenida/Selector/Hub, ver PLAN en
   TM2-EIOS (Smart Ecosystem → Smart Campus). Todo aditivo, nada de lo de
   arriba se modifica.
   ========================================================================== */

/* ---------- Lockup de texto (fallback mientras no hay logo real, ver
   src/Branding.php) ---------- */
.brand-logo { display: block; }
.brand-logo-text {
  display: inline-block; font-weight: 800; font-size: 22px; letter-spacing: -0.01em;
  color: var(--blue-deep);
}
.brand-logo-text .brand-accent { color: var(--green); }
.welcome-logo.brand-logo-text { font-size: 34px; }

/* ---------- Enlace "Volver al hub" en el topbar ---------- */
a.btn-back-hub {
  display: inline-flex; align-items: center; height: 36px; padding: 0 14px;
  border-radius: var(--sc-radius-md); background: transparent; border: 1px solid var(--sc-border);
  color: var(--sc-text-muted); font-size: 13px; font-weight: 600; gap: 4px;
}
a.btn-back-hub:hover { background: var(--sc-info-soft); color: var(--sc-primary); border-color: transparent; }

/* ---------- Selector de soluciones (tarjetas de producto) ---------- */
.solutions-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3);
  max-width: 980px; margin: var(--sp-3) auto 0;
}
@media (max-width: 860px) { .solutions-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .solutions-grid { grid-template-columns: 1fr; } }

.solution-card {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: var(--sp-3); text-align: left;
  display: flex; flex-direction: column; gap: 10px; text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease;
}
.solution-card.is-enabled:hover, .solution-card.is-enabled:focus-visible {
  transform: translateY(-2px); box-shadow: var(--shadow); outline: none;
}
.solution-card.is-enabled:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.solution-card.is-disabled { opacity: .6; cursor: default; }
.solution-card .solution-name { font-size: 17px; font-weight: 700; color: var(--ink); }
.solution-card .solution-desc { font-size: 13.5px; color: var(--muted); line-height: 1.5; flex-grow: 1; }
.solution-card .solution-cta { font-size: 13px; font-weight: 600; color: var(--blue-deep); }

.badge-soon {
  display: inline-flex; align-self: flex-start; font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: var(--radius-pill); background: #f1f1ef; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.badge-available {
  display: inline-flex; align-self: flex-start; font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: var(--radius-pill); background: var(--green-soft); color: var(--green-deep);
  text-transform: uppercase; letter-spacing: .04em;
}

/* ---------- Hub de perfiles (Smart Campus) ---------- */
.hub-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, auto);
  gap: var(--sp-3); max-width: 760px; margin: var(--sp-4) auto 0; align-items: center;
}
.hub-card {
  grid-column: span 1; aspect-ratio: 1 / 1; background: #fff; border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm); text-decoration: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: var(--sp-2); text-align: center; transition: transform .15s ease, box-shadow .15s ease;
}
.hub-card:hover, .hub-card:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow); }
.hub-card:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.hub-card:active { transform: scale(0.97); }
.hub-card .hub-icon { font-size: 30px; }
.hub-card .hub-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.hub-card .hub-desc { font-size: 12px; color: var(--muted); line-height: 1.4; }

.hub-card-admin     { grid-column: 1; grid-row: 1; }
.hub-card-profesor  { grid-column: 3; grid-row: 1; }
.hub-card-estudiante{ grid-column: 1; grid-row: 3; }
.hub-card-acudiente { grid-column: 3; grid-row: 3; }

.hub-circle-wrap { grid-column: 2; grid-row: 2; display: flex; justify-content: center; }
.hub-circle-btn {
  width: 148px; height: 148px; border-radius: 50%;
  background: linear-gradient(135deg, var(--blue), var(--blue-deep));
  color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; text-decoration: none; box-shadow: var(--shadow);
  transition: transform .15s ease, box-shadow .15s ease;
}
.hub-circle-btn:hover, .hub-circle-btn:focus-visible { transform: scale(1.04); }
.hub-circle-btn:focus-visible { outline: 3px solid var(--blue-deep); outline-offset: 4px; }
.hub-circle-btn:active { transform: scale(0.98); }
.hub-circle-btn .hub-circle-icon { font-size: 26px; }
.hub-circle-btn .hub-circle-label { font-size: 13px; font-weight: 700; text-align: center; line-height: 1.25; padding: 0 12px; }

@media (max-width: 640px) {
  .hub-grid {
    grid-template-columns: repeat(2, 1fr); grid-template-rows: auto auto auto; gap: var(--sp-2);
  }
  .hub-circle-wrap { grid-column: 1 / -1; grid-row: 1; margin-bottom: 4px; }
  .hub-card-admin      { grid-column: 1; grid-row: 2; }
  .hub-card-profesor   { grid-column: 2; grid-row: 2; }
  .hub-card-estudiante { grid-column: 1; grid-row: 3; }
  .hub-card-acudiente  { grid-column: 2; grid-row: 3; }
  .hub-card { aspect-ratio: auto; padding: var(--sp-2) 10px; min-height: 118px; }
  .hub-circle-btn { width: 128px; height: 128px; margin: 0 auto; }
}
@media (max-width: 340px) {
  .hub-grid { grid-template-columns: 1fr; }
  .hub-circle-wrap, .hub-card-admin, .hub-card-profesor, .hub-card-estudiante, .hub-card-acudiente {
    grid-column: 1;
  }
  .hub-card-admin { grid-row: 2; } .hub-card-profesor { grid-row: 3; }
  .hub-card-estudiante { grid-row: 4; } .hub-card-acudiente { grid-row: 5; }
}

/* ---------- Entrada escalonada discreta (tarjetas de soluciones/hub) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .solution-card, .hub-card, .hub-circle-wrap {
    animation: sc-stagger-in .35s ease both;
  }
  .solutions-grid > :nth-child(1), .hub-grid > :nth-child(1) { animation-delay: .02s; }
  .solutions-grid > :nth-child(2), .hub-grid > :nth-child(2) { animation-delay: .07s; }
  .solutions-grid > :nth-child(3), .hub-grid > :nth-child(3) { animation-delay: .12s; }
  .solutions-grid > :nth-child(4), .hub-grid > :nth-child(4) { animation-delay: .17s; }
  .solutions-grid > :nth-child(5), .hub-grid > :nth-child(5) { animation-delay: .22s; }
  .solutions-grid > :nth-child(6) { animation-delay: .27s; }
}
@keyframes sc-stagger-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Transicion de pagina premium (fade + zoom sutil) ----------
   Baseline CSS puro (funciona en todo navegador); se complementa —no se
   reemplaza— con la View Transitions API nativa via assets/js/transitions.js
   cuando el navegador la soporta. Respeta prefers-reduced-motion siempre. */
@media (prefers-reduced-motion: no-preference) {
  main.content, .welcome-screen {
    animation: sc-page-in .3s ease both;
  }
}
@keyframes sc-page-in {
  from { opacity: 0; transform: scale(1.02); }
  to   { opacity: 1; transform: scale(1); }
}
/* Nota: se probo @view-transition{navigation:auto} (cross-document View
   Transitions nativas) y se retiro — en pruebas reales causo
   AbortError/"Transition was skipped" que impedia la navegacion en algunos
   casos. "No bloquear la navegacion" es un requisito explicito, asi que el
   fade+scale de sc-page-in (arriba) queda como el unico mecanismo: 100%
   CSS, sin riesgo, mismo efecto visual percibido por el usuario. Bloque
   6-8 confirma explicitamente NO usar la View Transitions API — sigue
   siendo asi. */

/* ==========================================================================
   Bloque 6-8 — sistema de movimiento y componentes compartidos (2026-09-11)
   Aditivo: nada de lo de arriba se modifica salvo los tokens de :root ya
   redefinidos. Duraciones/curvas vienen de las variables de :root (§3 de
   la autorizacion): microinteraccion 140ms, componente 200ms, entrada de
   pagina <=300ms (sc-page-in ya usa 300ms, se deja igual).
   ========================================================================== */

/* ---------- Entrada de contenido reusable (tarjetas, filas de tabla,
   resultados de import/reportes) — mismo patron que sc-stagger-in pero
   como utilidad aplicable a cualquier elemento, no solo grids fijos. */
@media (prefers-reduced-motion: no-preference) {
  .sc-fade-in { animation: sc-fade-in-up var(--dur-page) var(--ease-out) both; }
  .sc-fade-in-1 { animation-delay: 40ms; }
  .sc-fade-in-2 { animation-delay: 80ms; }
  .sc-fade-in-3 { animation-delay: 120ms; }
  .sc-fade-in-4 { animation-delay: 160ms; }
}
@keyframes sc-fade-in-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Elevacion sutil para tarjetas interactivas (no decorativas) --
   uso: agregar a un .card que responde a click/hover real, no a cualquier
   tarjeta (evita "todo se mueve" que se siente ruidoso, no premium). */
.sc-liftable { transition: transform var(--dur-component) var(--ease-standard), box-shadow var(--dur-component) var(--ease-standard); }
.sc-liftable:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.sc-liftable:active { transform: translateY(0) scale(0.99); }

/* ---------- Foco unico y consistente -- cualquier control interactivo
   nuevo debe usar :focus-visible con este anillo, nunca un outline ad hoc. */
.btn:focus-visible, .sc-btn:focus-visible, .select:focus-visible, a:focus-visible, input:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible, summary:focus-visible {
  outline: 2px solid var(--sc-secondary);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}

/* ---------- Botones deshabilitados -- estado consistente en toda la app. */
.btn:disabled, .sc-btn:disabled, .btn[aria-disabled="true"] {
  opacity: .55; cursor: not-allowed; pointer-events: none;
}

/* ---------- Badges de rol / sede / estado / entorno (§2) -- una sola
   familia visual, diferenciada solo por color semantico. */
.sc-badge {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600;
  padding: 3px 10px; border-radius: var(--radius-pill); line-height: 1.6; white-space: nowrap;
}
.sc-badge-role     { background: var(--blue-soft); color: var(--blue-deep); }
.sc-badge-sede     { background: var(--gray-100); color: var(--ink); }
.sc-badge-success  { background: var(--state-success-soft); color: var(--state-success); }
.sc-badge-warning  { background: var(--state-warning-soft); color: var(--state-warning); }
.sc-badge-danger   { background: var(--state-danger-soft); color: var(--state-danger); }
.sc-badge-info     { background: var(--sc-info-soft); color: var(--sc-info); }
.sc-badge-neutral  { background: var(--gray-100); color: var(--sc-text-muted); }
.sc-badge-demo     { background: var(--blue-soft); color: var(--blue-deep); border: 1px solid rgba(59, 180, 255, 0.3); }

/* ---------- Estado vacio util (tablas/listas sin datos) -- reemplaza un
   "—" suelto por una explicacion breve + accion cuando aplica. */
.sc-empty {
  text-align: center; padding: var(--sp-3) var(--sp-2); color: var(--muted);
}
.sc-empty .sc-empty-icon { font-size: 26px; margin-bottom: 6px; display: block; }
.sc-empty .sc-empty-title { font-weight: 600; color: var(--ink); margin: 0 0 4px; }
.sc-empty .sc-empty-desc { font-size: 13px; margin: 0; }

/* ---------- Skeleton -- SOLO para espera real (import/reportes que
   consultan datos), nunca decorativo. */
.sc-skeleton {
  background: linear-gradient(90deg, var(--gray-100) 25%, var(--gray-200) 37%, var(--gray-100) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
}
@media (prefers-reduced-motion: no-preference) {
  .sc-skeleton { animation: sc-skeleton-sheen 1.4s ease infinite; }
}
@keyframes sc-skeleton-sheen {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* ---------- Toast de confirmacion accesible (guardar/importar/exportar) --
   markup + comportamiento en assets/js/ui.js; aqui solo la presentacion. */
.sc-toast-region {
  position: fixed; bottom: var(--sp-3); left: 50%; transform: translateX(-50%);
  z-index: 60; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none; width: min(92vw, 420px);
}
.sc-toast {
  pointer-events: auto; display: flex; align-items: center; gap: 10px;
  background: var(--blue-deep); color: #fff; border-radius: var(--radius-sm);
  padding: 12px 16px; font-size: 13.5px; font-weight: 500; box-shadow: var(--shadow-lift);
  width: 100%;
}
.sc-toast.sc-toast-success { background: var(--state-success); }
.sc-toast.sc-toast-danger { background: var(--state-danger); }
@media (prefers-reduced-motion: no-preference) {
  .sc-toast { animation: sc-toast-in var(--dur-component) var(--ease-out) both; }
  .sc-toast.sc-toast-out { animation: sc-toast-out var(--dur-component) var(--ease-standard) both; }
}
@media (prefers-reduced-motion: reduce) {
  .sc-toast.sc-toast-out { display: none; }
}
@keyframes sc-toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes sc-toast-out { from { opacity: 1; } to { opacity: 0; } }

/* ---------- Formularios divididos por secciones (Administracion,
   Importacion) -- reemplaza "una tarjeta = un formulario largo" por
   secciones con su propio titulo dentro de una misma tarjeta grande. */
.sc-section { padding: var(--sp-3) 0; border-top: 1px solid var(--border); }
.sc-section:first-child { border-top: none; padding-top: 0; }
.sc-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-bottom: var(--sp-2); flex-wrap: wrap; }
.sc-section-title { font-size: 15px; font-weight: 700; margin: 0; display: flex; align-items: center; gap: 8px; }
.sc-section-desc { font-size: 12.5px; color: var(--muted); margin: 2px 0 0; }

/* ---------- Navegacion por pestanas ancladas dentro de una pantalla
   (Administracion reorganizada, §4) -- pestanas de solo scroll+resaltado,
   sin JS de enrutado ni recarga. */
.sc-tabbar {
  display: flex; gap: 4px; flex-wrap: wrap; padding: 6px; background: var(--gray-50);
  border-radius: var(--radius-pill); margin: 0 auto var(--sp-3); width: fit-content; max-width: 100%;
  position: sticky; top: 68px; z-index: 5;
}
.sc-tabbar a {
  padding: 8px 16px; border-radius: var(--radius-pill); font-size: 13px; font-weight: 600;
  color: var(--muted); white-space: nowrap; transition: background-color var(--dur-micro) ease, color var(--dur-micro) ease;
}
.sc-tabbar a:hover { color: var(--blue-deep); }
.sc-tabbar a.is-current { background: #fff; color: var(--blue-deep); box-shadow: var(--shadow-sm); }

/* ---------- Doble-envio: boton de submit que se auto-deshabilita durante
   el envio real (assets/js/ui.js) — nunca en formularios GET/busqueda. */
.btn.is-submitting { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-submitting::after {
  content: ""; position: absolute; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.5); border-top-color: #fff;
}
.btn-secondary.is-submitting::after, .btn-soft.is-submitting::after, .btn-outline.is-submitting::after { border-color: rgba(11, 79, 138, 0.25); border-top-color: var(--sc-primary); }
@media (prefers-reduced-motion: no-preference) { .btn.is-submitting::after { animation: sc-spin .6s linear infinite; } }
@keyframes sc-spin { to { transform: rotate(360deg); } }

/* ---------- Filtros colapsables (Monitoreo Nacional, Reportes) --
   apertura/cierre con altura animada via JS (assets/js/ui.js). */
.sc-filter-panel { overflow: hidden; transition: grid-template-rows var(--dur-component) var(--ease-standard); display: grid; grid-template-rows: 0fr; }
.sc-filter-panel.is-open { grid-template-rows: 1fr; }
.sc-filter-panel > div { overflow: hidden; }
.sc-filter-panel-inner { padding-top: var(--sp-2); }

/* Todo lo de arriba respeta prefers-reduced-motion: las clases sin media
   query (sc-liftable transform, tabbar hover) son transiciones cortas de
   interfaz, no "movimiento" en el sentido de la pauta -- las animaciones
   con @keyframes (fade-in, skeleton, toast, spinner) SI estan guardadas
   bajo @media (prefers-reduced-motion: no-preference) arriba. */

/* ==========================================================================
   UI/UX PREMIUM (2026-09-14) -- AppShell unico por rol, ver la instruccion
   de esta fase. Reemplaza header.topbar/nav.tabs planos (Corte A) por:
   sidebar de escritorio + topbar fino + tabbar movil fija por oficio.
   Aditivo: las reglas de arriba (header.topbar, nav.tabs, etc.) quedan
   como respaldo/compatibilidad para cualquier pantalla que aun no adopte
   el shell, pero partials/header.php ya emite el shell en TODAS las
   paginas que lo usan (ver Corte A del reporte).
   ========================================================================== */

.sc-shell { min-height: 100vh; }

@media (min-width: 1024px) {
  .sc-shell.has-sidebar { display: flex; }
  .sc-sidebar {
    width: var(--sidebar-w); flex-shrink: 0; background: var(--sc-surface); color: var(--sc-text);
    border-right: 1px solid var(--sc-border);
    display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto;
  }
  .sc-shell-main { flex: 1; min-width: 0; }
}
@media (max-width: 1023.98px) {
  .sc-sidebar { display: none; }
}

.sc-sidebar-brand { padding: 18px 18px 16px; display: flex; align-items: center; gap: 10px; }
/* SHELL + OFICIO, Sección 19 -- el logo horizontal a su ancho real
   (~155px, dentro del rango 145-165px pedido), no un ícono de 30px de
   alto metido en una cápsula redonda ("favicon dentro de cápsula
   blanca"). El fondo blanco se mantiene (el asset es navy/celeste sobre
   transparente; el sidebar es --blue-deep oscuro, sin fondo claro el
   texto navy se perdería) pero como una tarjeta generosa, no un chip
   ajustado al ícono. */
.sc-sidebar-brand img.logo { width: 155px; height: auto; max-width: 100%; object-fit: contain; display: block; }
.sc-sidebar-context { padding: 0 18px 14px; font-size: 12px; color: var(--sc-text-muted); line-height: 1.4; }
.sc-sidebar-context strong { display: block; color: var(--sc-text); font-size: 13.5px; font-weight: 600; }

.sc-sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 4px 12px; flex: 1; overflow-y: auto; }
.sc-sidebar-nav a {
  display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 10px;
  color: var(--sc-text-muted); font-size: 13.5px; font-weight: 500; transition: background-color var(--dur-micro) ease;
}
.sc-sidebar-nav a:hover { background: var(--sc-surface-subtle); color: var(--sc-text); }
.sc-sidebar-nav a.active { background: var(--sc-info-soft); color: var(--sc-primary); font-weight: 600; }
.sc-sidebar-nav svg { flex-shrink: 0; }

/* ---------- "Mas" del sidebar (UI premium T2, Seccion C) -- <details>
   nativo, funciona sin JS. Mismo objetivo que sc-more de la tabbar
   movil pero como sub-lista inline, no como hoja fija. ---------- */
.sc-sidebar-more { margin-top: 2px; }
.sc-sidebar-more > summary {
  display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 10px;
  color: var(--sc-text-muted); font-size: 13.5px; font-weight: 500; cursor: pointer; list-style: none;
}
.sc-sidebar-more > summary::-webkit-details-marker { display: none; }
.sc-sidebar-more > summary:hover { background: var(--sc-surface-subtle); color: var(--sc-text); }
.sc-sidebar-more[open] > summary { color: var(--sc-text); }
.sc-sidebar-more-panel { display: flex; flex-direction: column; gap: 2px; padding-left: 14px; margin-top: 2px; }
.sc-sidebar-more-panel a {
  display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: 10px;
  color: var(--sc-text-muted); font-size: 13px; font-weight: 500;
}
.sc-sidebar-more-panel a:hover { background: var(--sc-surface-subtle); color: var(--sc-text); }
.sc-sidebar-more-panel a.active { background: var(--sc-info-soft); color: var(--sc-primary); font-weight: 600; }

.sc-sidebar-foot { padding: 14px 18px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--sc-border); font-size: 12.5px; color: var(--sc-text-muted); }
.sc-sidebar-foot .sc-sidebar-person { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sc-sidebar-foot .sc-sidebar-person > span.sc-ellipsis { min-width: 0; }
.sc-sidebar-foot a.sc-logout-link { color: var(--sc-primary); font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 36px; height: 36px; border-radius: var(--sc-radius-md); }
.sc-sidebar-foot a.sc-logout-link:hover { background: var(--sc-info-soft); }

/* ---------- Topbar fino: unico header de producto, igual en todas las
   pantallas que usan el shell (reemplaza el header.topbar "comercial"
   con la fila publica + fila de personal apiladas). ---------- */
.sc-topbar {
  background: rgba(255, 255, 255, 0.86); backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 20;
  height: var(--topbar-h); padding: 0 var(--sp-3); display: flex; align-items: center;
  justify-content: space-between; gap: var(--sp-2);
}
.sc-topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sc-topbar-left img.logo { height: clamp(22px, 5vw, 30px); width: auto; max-width: 100%; object-fit: contain; flex-shrink: 0; }
/* Modo vista de celular EN PANTALLAS SIN SIDEBAR (login/hub/marca): el
   logo pasa a ser el elemento dominante, centrado en la barra -- estas
   pantallas solo llevan 1-2 controles ligeros a los lados, hay espacio. */
@media (max-width: 640px) {
  .sc-shell:not(.has-sidebar) .sc-topbar-left img.logo {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    height: 38px;
  }
  .sc-shell:not(.has-sidebar) .sc-topbar-left { justify-content: flex-start; }
}

/* SHELL + OFICIO, Sección 21 -- header móvil de 2 líneas del shell
   AUTENTICADO (.has-sidebar): línea 1 = logo Smart Campus centrado
   (.sc-topbar-brand), línea 2 = institución + Demo + Salir
   (topbar-left/topbar-right de siempre). En escritorio el sidebar YA
   muestra el logo -- .sc-topbar-brand se oculta ahí para no duplicarlo. */
.sc-topbar-brand { display: none; }
@media (max-width: 1023.98px) {
  .sc-shell.has-sidebar .sc-topbar {
    flex-wrap: wrap; height: auto; padding: 10px var(--sp-3) 8px; row-gap: 6px;
  }
  .sc-shell.has-sidebar .sc-topbar-brand {
    display: block; width: 100%; text-align: center; order: 1;
  }
  .sc-shell.has-sidebar .sc-topbar-brand img.logo {
    height: 30px; width: auto; object-fit: contain; margin: 0 auto;
  }
  .sc-shell.has-sidebar .sc-topbar-left { order: 2; }
  .sc-shell.has-sidebar .sc-topbar-right { order: 3; }
}
.sc-topbar-sede { font-size: 13.5px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* UX Consistencia: recorte SOLO visual de nombres largos (sede, persona)
   -- el valor completo siempre vive en el atributo title="" del mismo
   elemento (ver DisplayName::sede()/header.php), nunca truncado en PHP. */
.sc-ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; max-width: 100%; }
.sc-topbar-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.sc-topbar-person { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
@media (max-width: 1023.98px) { .sc-topbar-sede { max-width: 46vw; } }
/* En escritorio la sede ya se ve en el contexto del sidebar -- no
   repetirla tambien en el topbar fino (solo se necesita en movil, donde
   el sidebar esta oculto). */
@media (min-width: 1024px) { .sc-shell.has-sidebar .sc-topbar-sede { display: none; } }
/* Una sola forma de Salir (baja #7): en escritorio el sidebar ya trae la
   suya, el boton del topbar solo hace falta en movil (sidebar oculto). */
@media (min-width: 1024px) { .sc-shell.has-sidebar .sc-topbar-logout { display: none; } }

/* ---------- Chip demo: UNO solo, en el topbar, nunca repetido por
   pantalla (baja obligatoria #5 de la instruccion). ---------- */
.sc-demo-chip {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600;
  height: 24px; padding: 0 10px; border-radius: 999px; background: var(--blue-soft); color: var(--blue-deep);
  border: 1px solid rgba(46, 163, 255, 0.25); white-space: nowrap;
}

/* ---------- RC-3 Ola F: banner de "Explorar como" (solo demo) ----------
   En flujo normal (no sticky) a propósito: esta app recarga la página completa
   en cada navegación (sin router cliente), así que "permanente" ya se cumple
   reapareciendo arriba en cada carga -- pelear con el sidebar sticky (también
   top:0, ver .sc-sidebar) por quién gana el scroll no aporta nada real. */
.sc-explore-banner {
  display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
  padding: 10px var(--sp-3); background: var(--sc-warning-soft, #FFFBEB); color: var(--sc-warning, #B45309);
  border-bottom: 1px solid rgba(180, 83, 9, 0.25); font-size: 13px; font-weight: 500; text-align: center;
}
.sc-explore-banner .btn { flex-shrink: 0; }

/* ---------- Tabbar movil fija por oficio (Corte A) ---------- */
.sc-tabbar-mobile {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; display: flex;
  background: #fff; border-top: 1px solid var(--border); box-shadow: 0 -4px 16px rgba(15, 39, 64, 0.06);
  padding-bottom: env(safe-area-inset-bottom);
}
.sc-tabbar-mobile a, .sc-tabbar-mobile summary {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 8px 4px 7px; font-size: 11px; font-weight: 600; color: var(--muted);
  list-style: none; cursor: pointer; min-height: 56px;
}
.sc-tabbar-mobile summary::-webkit-details-marker { display: none; }
.sc-tabbar-mobile a.active, .sc-tabbar-mobile .sc-more[open] summary { color: var(--sc-primary); }
.sc-tabbar-mobile a.active { box-shadow: inset 0 2px 0 var(--sc-primary); }
.sc-tabbar-mobile svg { width: 22px; height: 22px; }
/* RC-2: los 5 destinos comparten el ancho por igual ("Mas" es un <details>, sin
   esto queda con ancho de contenido y se recorta contra el borde en 375px). */
.sc-tabbar-mobile > a, .sc-tabbar-mobile > .sc-more { flex: 1 1 0; min-width: 0; }
.sc-tabbar-mobile > .sc-more > summary { width: 100%; }
.sc-tabbar-mobile span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 1024px) { .sc-tabbar-mobile { display: none; } }

/* "Mas": <details> nativo -- funciona sin JS, foco/teclado gratis. El
   panel es fixed (escapa del flujo del <details>) asi que puede
   posicionarse como hoja inferior sin JS de overlay. */
.sc-more { position: static; }
.sc-more-panel {
  display: none; position: fixed; left: 0; right: 0; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  max-height: 60vh; overflow-y: auto; background: #fff; border-top: 1px solid var(--border);
  border-radius: 16px 16px 0 0; box-shadow: 0 -8px 30px rgba(15, 39, 64, 0.16); padding: 8px;
  z-index: 41;
}
.sc-more[open] .sc-more-panel { display: block; }
.sc-more-panel a {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 10px;
  font-size: 14px; font-weight: 500; color: var(--ink);
}
.sc-more-panel a:hover { background: var(--gray-50); }
.sc-more-panel a svg { color: var(--muted); flex-shrink: 0; }
/* NAV OFICIO v1, Sección 6 -- rótulo de grupo dentro de "Más" (profesor);
   ajuste fino, no un rediseño del panel. */
.sc-more-group-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--muted); padding: 10px 14px 4px;
}
.sc-more-group-label:first-child { padding-top: 4px; }

/* Cuando hay tabbar movil, el contenido no debe quedar tapado por ella. */
.has-mobile-tabbar main.content { padding-bottom: calc(var(--tabbar-h) + var(--sp-3) + env(safe-area-inset-bottom)); }
@media (min-width: 1024px) { .has-mobile-tabbar main.content { padding-bottom: 72px; } }

main.content { max-width: 1120px; }
.sc-shell.has-sidebar .sc-shell-main main.content { max-width: 1120px; }

/* ---------- Cabecera de pantalla (titulo + contexto + 1-2 acciones) ---------- */
.sc-pagehead { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.sc-pagehead-title, h1.title, h2.title { font-size: var(--sc-fs-h1); line-height: var(--sc-lh-h1); font-weight: 700; margin: 0; color: var(--sc-text); letter-spacing: -0.01em; }
.sc-pagehead.is-center { justify-content: center; text-align: center; }
.sc-pagehead.is-center .sc-pagehead-context { margin-left: auto; margin-right: auto; }
.sc-pagehead-context { font-size: 13px; color: var(--muted); margin: 4px 0 0; }
.sc-pagehead-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* ---------- Fila de KPIs (maximo 4, reusa .stat) ---------- */
.sc-kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-2); margin-bottom: var(--sp-3); }
@media (max-width: 640px) { .sc-kpi-row { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Mismo dato en dos pieles: tabla (escritorio) / lista de
   tarjetas (movil) -- alternar con utilidades de visibilidad. ---------- */
.sc-card-list { display: flex; flex-direction: column; gap: 10px; }
.sc-card-list-item {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm); padding: 14px 16px; display: flex; align-items: center;
  justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.sc-only-desktop { display: none; }
.sc-only-mobile { display: block; }
@media (min-width: 768px) {
  .sc-only-desktop { display: block; }
  .sc-only-mobile { display: none; }
}

/* ---------- Pills de estado -- un vocabulario visual unico para
   presente/tardanza/ausente/pendiente/activo en toda la app. ---------- */
.sc-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 999px; line-height: 1.5; white-space: nowrap; }
.sc-pill-presente, .sc-pill-activo { background: var(--state-success-soft); color: var(--state-success); }
.sc-pill-tardanza { background: var(--state-warning-soft); color: var(--state-warning); }
.sc-pill-ausente { background: var(--state-danger-soft); color: var(--state-danger); }
.sc-pill-pendiente { background: var(--gray-100); color: var(--muted); }

/* ---------- Tarjeta de autenticacion -- unico patron para login de
   personal, login de familia y activacion de cuenta. ---------- */
.sc-auth-card { max-width: 380px; margin: 8vh auto; padding: var(--sp-4) var(--sp-3); box-shadow: var(--shadow); }
.sc-auth-card .sc-auth-title { font-size: var(--sc-fs-h1); line-height: var(--sc-lh-h1); font-weight: 700; margin: 0 0 4px; text-align: center; color: var(--sc-text); }
.sc-auth-card .sc-auth-sub { font-size: 13px; color: var(--muted); text-align: center; margin: 0 0 var(--sp-3); }

/* RC-4 -- Sección 2: contraseña oculta por defecto con mostrar/ocultar,
   solo en la entrada comercial de Smart Campus (ver staff-login.php). */
.sc-password-field { position: relative; display: flex; }
.sc-password-field input { flex: 1; padding-right: 40px; }
.sc-password-toggle { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; font-size: 16px; padding: 6px 8px; line-height: 1; opacity: .65; }
.sc-password-toggle:hover { opacity: 1; }

/* ---------- Wizard de import (plantilla -> subir -> preview -> confirmar) ---------- */
.sc-wizard-steps { display: flex; gap: 6px; margin-bottom: var(--sp-3); flex-wrap: wrap; }
.sc-wizard-step { font-size: 12px; font-weight: 600; padding: 6px 14px; border-radius: 999px; background: var(--gray-100); color: var(--muted); }
.sc-wizard-step.is-current { background: var(--blue-deep); color: #fff; }
.sc-wizard-step.is-done { background: var(--state-success-soft); color: var(--state-success); }

/* ---------- Modal simple (token de activacion, confirmaciones) -- HTML
   nativo <dialog>, sin libreria. Degrada a bloque siempre-visible si el
   navegador no soporta <dialog> (progresivo, igual que el resto de
   assets/js/ui.js). ---------- */
dialog.sc-modal {
  border: none; border-radius: var(--radius-card); box-shadow: var(--shadow-lift);
  padding: var(--sp-3); max-width: 440px; width: min(92vw, 440px); margin: auto;
}
dialog.sc-modal::backdrop { background: rgba(15, 39, 64, 0.45); }
.sc-modal-title { font-size: 16px; font-weight: 700; margin: 0 0 6px; display: flex; align-items: center; gap: 8px; }
.sc-modal-body { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 0 0 var(--sp-2); }
.sc-modal-token { font-family: ui-monospace, monospace; font-size: 12px; word-break: break-all; background: var(--gray-50); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: var(--sp-2); }
.sc-modal-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }

/* ---------- Estado vacio de "lista del dia" y similares con icono de
   trazo (reemplaza el emoji generico de .sc-empty cuando se usa uno). ---------- */
.sc-empty-icon-svg { width: 34px; height: 34px; color: var(--muted); margin: 0 auto 8px; display: block; }

/* ---------- UI premium T2: "una vista a la vez" (admin.php/padres.php) --
   [hidden] ya es display:none por la hoja de estilos del navegador; esta
   regla es explicita para que ningun selector futuro de mayor
   especificidad la pise por accidente. ---------- */
.sc-view-section[hidden] { display: none; }


/* ---------- RC-2: acceso no autorizado (403) -- componente unico
   sc_access_denied(), ver public/partials/access-denied.php ---------- */
.sc-access-denied { max-width: 480px; margin: 0 auto; text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--sc-space-3); padding: var(--sp-4) var(--sp-3); }
.sc-access-denied > svg { width: 34px; height: 34px; color: var(--sc-danger); }
.sc-access-denied-msg { margin: 0; color: var(--sc-text); font-size: var(--sc-fs-body); line-height: 1.6; }
.sc-access-denied p { margin: 0; }

/* ---------- RC-2: utilidades de escala (reemplazan estilos inline repetidos;
   !important a proposito: un atributo style="" ganaba a cualquier clase y la
   utilidad debe conservar esa precedencia). Escala: xs 11.5 / small 12.5;
   espaciado 8 (mt-1) y 16/24 (mt-2, mb-2, mb-3). ---------- */
.sc-text-small { font-size: var(--sc-fs-small) !important; }
.sc-text-xs { font-size: 11.5px !important; }
.sc-text-success { color: var(--sc-success) !important; }
.sc-text-danger { color: var(--sc-danger) !important; }
.sc-mt-1 { margin-top: var(--sc-space-2) !important; }
.sc-mt-2 { margin-top: var(--sp-2) !important; }
.sc-mb-2 { margin-bottom: var(--sp-2) !important; }
.sc-mb-3 { margin-bottom: var(--sp-3) !important; }

/* RC-2: lineas de estado (jornada CampusStatus, recuento de secciones) -- texto
   en linea centrado; .center es flex en columna y apilaba el punto y el icono
   sobre el texto. Solo presentacion: el contenido/logica no cambia. */
.sc-status-line { display: block; text-align: center; }

/* ---------- RC-3 Addendum: mapa de Monitor Nacional + drawer de sede ----------
   Provincia de Panamá primero (Sección 5), arquitectura lista para más
   provincias/vista nacional (chips debajo, mismo componente). */
.sc-map-province {
  position: relative; border: 1px solid var(--sc-border, var(--border)); border-radius: var(--sc-radius-lg, 16px);
  background: var(--sc-surface-subtle, #F4F7FB); min-height: 260px; padding: var(--sp-3);
  display: flex; flex-wrap: wrap; gap: var(--sp-3); align-content: flex-start;
}
.sc-map-province-label {
  position: absolute; top: 10px; left: 14px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--sc-text-muted, var(--muted));
}
.sc-map-marker {
  display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: none; cursor: pointer;
  padding: 28px 8px 6px; font: inherit; color: inherit; min-width: 84px;
}
.sc-map-marker-dot {
  width: 16px; height: 16px; border-radius: 999px; background: var(--sc-danger, #C62828);
  box-shadow: 0 0 0 4px rgba(198, 40, 40, .12); flex-shrink: 0;
}
.sc-map-marker.is-online .sc-map-marker-dot {
  background: var(--sc-success, #1A7F4B); box-shadow: 0 0 0 4px rgba(26, 127, 75, .16);
  animation: sc-pulse 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .sc-map-marker.is-online .sc-map-marker-dot { animation: none; } }
@keyframes sc-pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(26, 127, 75, .16); }
  50% { box-shadow: 0 0 0 8px rgba(26, 127, 75, .08); }
}
.sc-map-marker-name { font-size: 12px; font-weight: 600; text-align: center; max-width: 100px; }
.sc-map-marker-city { font-size: 11px; color: var(--sc-text-muted, var(--muted)); }
.sc-map-marker:hover, .sc-map-marker:focus-visible { background: rgba(11, 79, 138, .06); border-radius: 12px; }

/* Monitor Nacional Visual Redesign -- mapa geográfico enterprise/SaaS
   (reemplaza el fondo azul tipo ilustración + relleno beige de RC-4).
   Paleta EXCLUSIVAMENTE del Design System (blanco, navy/azul de marca,
   verde/ámbar/rojo de estado) -- ver Sección 2 de la instrucción. */
.sc-map-geo {
  /* 15/7 == viewBox de public/partials/panama-map.php (900x420) -- deben
     coincidir exactamente para que las coordenadas de los marcadores
     (calculadas en % sobre ese mismo viewBox) caigan en el pixel
     correcto, sin letterboxing del SVG.
     Auditoría de consejo: un min-height:220px anterior GANABA sobre
     aspect-ratio en contenedores angostos (menos de ~471px de ancho), la
     caja dejaba de ser 15/7 y el SVG (preserveAspectRatio por defecto)
     quedaba más bajo que su contenedor con bandas vacías -- los
     marcadores (posicionados en % sobre el ALTO del contenedor) caían
     hasta 32px fuera de su provincia real a 375px (medido con
     Playwright: Colón terminaba en el Caribe). Sin min-height,
     aspect-ratio controla el alto en cualquier ancho, siempre 15/7 real. */
  position: relative; width: 100%; aspect-ratio: 15 / 7;
  border: 1px solid var(--sc-border, var(--border)); border-radius: var(--sc-radius-lg, 16px);
  background: var(--sc-surface-subtle, #F4F7FB); overflow: hidden;
}
.sc-map-geo-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.sc-map-geo-shape { fill: #E4E9F1; stroke: var(--sc-primary, #0B4F8A); stroke-width: 1.4; stroke-opacity: .55; }
.sc-map-geo-borders path {
  fill: none; stroke: rgba(15, 39, 64, .22); stroke-width: 1; stroke-dasharray: 3 3;
}
/* Auditoría de consejo: las zonas quedan SIN cursor:pointer/hover a
   propósito -- los <rect> (public/partials/panama-map.php) no tienen
   ningún manejador de clic todavía (arquitectura lista para un futuro
   filtro por provincia, Sección 1), así que pintarlas como clicables
   era una trampa: el cursor cambiaba y el fondo resaltaba sobre un
   control que no hacía nada al soltar el clic. Cuando exista el filtro
   real, esta regla vuelve. */
.sc-map-province-zone { pointer-events: none; }
.sc-map-province-text {
  font-size: 11px; font-weight: 600; fill: var(--sc-text-muted, var(--muted)); text-anchor: middle; pointer-events: none;
}
@media (max-width: 640px) { .sc-map-province-text { display: none; } }

.sc-map-geo-marker {
  position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center;
  gap: 2px; background: none; border: none; cursor: pointer; padding: 4px; font: inherit; color: inherit; z-index: 2;
}
.sc-map-geo-marker .sc-map-marker-dot {
  width: 13px; height: 13px; border-radius: 999px; background: var(--sc-danger, #c62828);
  box-shadow: 0 0 0 4px rgba(198, 40, 40, .16); flex-shrink: 0; display: block;
}
.sc-map-geo-marker.is-online .sc-map-marker-dot {
  background: var(--sc-success, #1a7f4b); box-shadow: 0 0 0 4px rgba(26, 127, 75, .16);
  animation: sc-pulse 2.4s ease-in-out infinite;
}
.sc-map-geo-marker.is-attention .sc-map-marker-dot {
  background: var(--sc-warning, #b45309); box-shadow: 0 0 0 4px rgba(180, 83, 9, .16);
}
@media (prefers-reduced-motion: reduce) { .sc-map-geo-marker.is-online .sc-map-marker-dot { animation: none; } }
.sc-map-geo-label { display: none; }
.sc-map-geo-marker:hover .sc-map-geo-label,
.sc-map-geo-marker:focus-visible .sc-map-geo-label {
  display: block; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  background: var(--sc-surface, #fff); border: 1px solid var(--sc-border, var(--border)); border-radius: 8px;
  padding: 4px 8px; font-size: 11px; font-weight: 600; white-space: nowrap; box-shadow: var(--shadow, 0 2px 8px rgba(0,0,0,.12));
  z-index: 5; text-align: center;
}
.sc-map-geo-status-word { display: block; font-weight: 700; }
.sc-map-geo-city { font-weight: 400; color: var(--sc-text-muted, var(--muted)); }
@media (max-width: 640px) {
  /* Se mantiene 15/7 (igual que desktop) a propósito -- cambiar el
     aspect-ratio del contenedor sin cambiar el viewBox distorsiona el
     contorno del SVG. */
  .sc-map-geo-marker .sc-map-marker-dot { width: 16px; height: 16px; }
}

/* ---------- Header ejecutivo + KPI banda + right rail "Red Educativa" ---------- */
.sc-monitor-header {
  display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-3); flex-wrap: wrap;
  max-width: 1120px; margin: 0 auto 20px;
}
.sc-monitor-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--sc-secondary, #2EA3FF); margin: 0 0 4px;
}
.sc-monitor-title { font-size: 26px; font-weight: 800; color: var(--sc-primary, #0B4F8A); margin: 0; line-height: 1.2; }
.sc-monitor-sub {
  font-size: 13px; color: var(--sc-text-muted, var(--muted)); margin: 8px 0 0; display: flex; flex-wrap: wrap;
  gap: 4px 8px; align-items: center;
}
.sc-monitor-sub .sep { opacity: .5; }
.sc-monitor-sub strong { color: var(--sc-text, inherit); font-weight: 700; }

.sc-monitor-layout {
  /* minmax(0,1fr) en vez de 1fr solo: fija el bug de overflow en la
     COLUMNA del grid misma (nunca deja que un hijo intrínsecamente ancho
     la vuelva a estirar), en vez de depender solo de min-width:0 en cada
     hijo -- técnica más robusta para cualquier contenido futuro dentro
     de esta columna (ver CSS-Tricks "Preventing a Grid Blowout"). */
  display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--sp-3); max-width: 1120px; margin: 0 auto var(--sp-3);
  align-items: start;
}
@media (max-width: 900px) { .sc-monitor-layout { grid-template-columns: minmax(0, 1fr); } }
/* Bug clásico de CSS Grid: un ítem de grid no se encoge por debajo del
   ancho intrínseco de su contenido (min-width:auto por defecto) -- sin
   esto, el SVG del mapa empujaba TODO el layout más ancho que el
   viewport a 375px (170px de overflow horizontal real, detectado por
   Playwright). min-width:0 fuerza a que el ítem respete el ancho de su
   columna del grid en vez del de su contenido. */
.sc-monitor-main, .sc-monitor-rail { min-width: 0; }

.sc-monitor-rail {
  border: 1px solid var(--sc-border, var(--border)); border-radius: var(--sc-radius-lg, 16px);
  background: var(--sc-surface, #fff); padding: var(--sp-3);
}
@media (min-width: 901px) { .sc-monitor-rail { position: sticky; top: 16px; } }
.sc-rail-list { display: flex; flex-direction: column; }
.sc-rail-row {
  display: flex; align-items: center; gap: 8px; padding: 9px 2px; border-bottom: 1px solid var(--sc-border, var(--border));
  cursor: pointer; font: inherit; background: none; border-left: none; border-right: none; border-top: none;
  width: 100%; text-align: left; color: inherit;
}
.sc-rail-row:last-child { border-bottom: none; }
.sc-rail-row:hover, .sc-rail-row:focus-visible { background: rgba(46, 163, 255, .06); }
.sc-rail-dot { width: 9px; height: 9px; border-radius: 999px; flex-shrink: 0; }
.sc-rail-dot.online { background: var(--sc-success, #1a7f4b); }
.sc-rail-dot.attention { background: var(--sc-warning, #b45309); }
.sc-rail-dot.offline { background: var(--sc-danger, #c62828); }
.sc-rail-info { min-width: 0; flex: 1; }
.sc-rail-name { font-weight: 600; font-size: 13px; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-rail-meta { font-size: 11px; color: var(--sc-text-muted, var(--muted)); display: block; }
.sc-rail-pct { font-size: 12px; font-weight: 700; white-space: nowrap; flex-shrink: 0; }

.sc-map-disclosure {
  display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--sc-text-muted, var(--muted)); margin-top: 10px;
}
.sc-map-disclosure-info {
  border: 1px solid var(--sc-border, var(--border)); border-radius: 999px; width: 16px; height: 16px; line-height: 14px;
  text-align: center; font-size: 10px; font-weight: 700; background: none; cursor: pointer; color: var(--sc-text-muted, var(--muted));
  padding: 0;
}
.sc-map-methodology { font-size: 11px; color: var(--sc-text-muted, var(--muted)); margin: 6px 0 0; }
.sc-map-methodology[hidden] { display: none; }

/* Mobile (375px, Sección 9): mapa arriba, KPIs en grid 2x2 (ya cubierto
   por .grid-4 -- ver style.css línea ~365), listado de sedes debajo del
   mapa, cero overflow horizontal.
   Auditoría de consejo: el DOM tenía 11 tarjetas de KPI + 3 tarjetas de
   navegación ANTES del mapa -- en un teléfono real eso empuja el mapa
   muy por debajo del pliegue, al revés de lo que pide esta sección. Se
   reordena solo visualmente con `order` (nunca se mueve el mapa en el
   DOM real, evita cualquier problema de foco/lectura de pantalla). */
@media (max-width: 640px) {
  .sc-monitor-header { flex-direction: column; }
  .sc-monitor-content { display: flex; flex-direction: column; }
  .sc-monitor-content .sc-monitor-layout { order: -1; }
}

.sc-province-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--sp-2); }
.sc-province-chip {
  display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--sc-border, var(--border));
  border-radius: 999px; padding: 6px 12px; font-size: 12px; background: var(--sc-surface, #fff); cursor: pointer; font: inherit;
}
.sc-province-chip .dot { width: 8px; height: 8px; border-radius: 999px; flex-shrink: 0; }
.sc-province-chip .dot.online { background: var(--sc-success, #1A7F4B); }
.sc-province-chip .dot.attention { background: var(--sc-warning, #b45309); }
.sc-province-chip .dot.offline { background: var(--sc-danger, #C62828); }
.sc-chip-status { color: var(--sc-text-muted, var(--muted)); font-size: 11px; }

.sc-sede-drawer { position: fixed; inset: 0; z-index: 80; }
.sc-sede-drawer-backdrop { position: absolute; inset: 0; background: rgba(15, 39, 64, .45); }
.sc-sede-drawer-panel {
  position: absolute; top: 0; right: 0; height: 100%; width: min(420px, 100vw); background: var(--sc-surface, #fff);
  box-shadow: -8px 0 24px rgba(15, 39, 64, .18); padding: var(--sp-4) var(--sp-3); overflow-y: auto;
}
@media (max-width: 640px) {
  .sc-sede-drawer-panel { top: auto; bottom: 0; right: 0; left: 0; width: 100%; height: auto; max-height: 82vh;
    border-radius: 16px 16px 0 0; box-shadow: 0 -8px 24px rgba(15, 39, 64, .18); }
}
.sc-sede-drawer-close { position: absolute; top: 10px; right: 12px; background: none; border: none; font-size: 18px; cursor: pointer; padding: 6px; }
.sc-sede-drawer-eyebrow { font-size: 12px; font-weight: 700; color: var(--sc-text-muted, var(--muted)); margin: 0 0 4px; }
.sc-sede-drawer-title { font-size: 20px; margin: 0 0 2px; }
.sc-sede-drawer-sub { font-size: 13px; color: var(--sc-text-muted, var(--muted)); margin: 0 0 16px; }
.sc-sede-drawer-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.sc-sede-drawer-grid .value { display: block; font-size: 20px; font-weight: 700; }
.sc-sede-drawer-grid .label { display: block; font-size: 11.5px; color: var(--sc-text-muted, var(--muted)); }
.sc-sede-drawer-row { font-size: 13px; margin: 0 0 8px; }
tr[data-sede] { cursor: pointer; }
tr[data-sede]:hover { background: var(--sc-surface-subtle, #F4F7FB); }
.sc-status-line svg { width: 16px; height: 16px; vertical-align: -3px; }
