/* ─────────────────────────────────────────────────────────────────────────────
 * sistema.css — el sistema visual de Doctrix.
 *
 * Tipografía, colores, densidad y las piezas que se repiten en todas las
 * pantallas (botones, campos, tablas, tarjetas, menú lateral y barra superior).
 * Se carga la ÚLTIMA de todas las hojas (ver index.html): lo de aquí manda.
 *
 * Por qué existe: la app llegó a tener 218 colores, 106 tamaños de letra, 152
 * sombras y 12 radios distintos, porque cada pantalla se escribió con sus
 * propios valores encima de las variables. El modelo es AulaTrix: pocas
 * variables, y todo lo demás se deriva de ellas. Claro y oscuro salen de la
 * misma escala, así que se ven hermanos; el menú lateral sigue al tema.
 *
 * REGLA: no escribir colores, tamaños ni sombras fijos en pantallas nuevas.
 * Usar las variables de abajo (--text-main, --border, --h-control…).
 *
 * El color institucional de cada centro sigue controlando --primary (lo pone
 * js/branding.js en línea sobre <html> y <body>, y eso gana a esta hoja).
 * ────────────────────────────────────────────────────────────────────────── */

/* Inter, servida desde el propio dominio: sin depender de Google Fonts (falla
   con internet débil) ni de la fuente del sistema del teléfono. Un solo
   archivo variable por subconjunto; latin y latin-ext cubren el español. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/inter-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── 1. Variables ─────────────────────────────────────────────────────────
   Se declaran sobre <body> (no :root) porque así lo hacen style.css y la capa
   Horizonte para el modo oscuro: una variable en <body> gana a la heredada de
   <html>, y al cargar después, esta hoja gana a las dos. Se redefinen también
   las --dx-* de Horizonte, que muchas reglas viejas leen directamente. */
body {
  color-scheme: light;

  /* Superficies */
  --dx-canvas: #f6f7f9;
  --dx-canvas-subtle: #eef0f4;
  --dx-surface: #ffffff;
  --dx-surface-raised: #ffffff;
  --dx-surface-muted: #f6f7f9;
  --dx-sidebar: #f6f7f9;
  --dx-sidebar-deep: #f6f7f9;
  --bg-main: var(--dx-canvas);
  --bg-card: var(--dx-surface);
  --bg-sidebar: var(--dx-sidebar);
  --input-bg: #ffffff;
  --bg-input: var(--input-bg);
  --campo-fondo: #ffffff;
  --surface-glass: #f6f7f9;
  --surface-glass-hover: rgba(23, 27, 44, .045);
  --bg-hover: var(--surface-glass-hover);

  /* Texto: tres niveles y ninguno más. */
  --dx-text: #171b2c;
  --dx-text-secondary: #3c4257;
  --dx-text-muted: #5b6275;
  --text-main: var(--dx-text);
  --text-muted: var(--dx-text-muted);
  --text-faint: #6b7285;

  /* Bordes */
  --dx-border: #e3e6ee;
  --dx-border-strong: #cdd2de;
  --border: var(--dx-border);
  --border-strong: var(--dx-border-strong);
  --border-glass: var(--dx-border);
  --border-glass-active: var(--dx-border-strong);

  /* Estados, con contraste ≥ 4.5:1 sobre su propio relleno suave. */
  /* #15803d daba 4,47:1 sobre su propio fondo suave (etiquetas «Activo»,
     «Aprobada», estado del plan): bajo el mínimo AA. */
  --dx-success: #136f37;
  --dx-warning: #92400e;
  --dx-danger: #b91c1c;
  --dx-info: #0369a1;
  --success: var(--dx-success);
  --warning: var(--dx-warning);
  --danger: var(--dx-danger);
  --success-soft: color-mix(in srgb, var(--dx-success) 9%, var(--bg-card));
  --warning-soft: color-mix(in srgb, var(--dx-warning) 9%, var(--bg-card));
  --danger-soft: color-mix(in srgb, var(--dx-danger) 9%, var(--bg-card));

  /* Forma: dos radios (control y panel) y una sombra, solo para lo que flota. */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 12px;
  --dx-shadow-1: none;
  --dx-shadow-2: 0 12px 32px -12px rgba(15, 23, 42, .30);
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: 0 12px 32px -12px rgba(15, 23, 42, .30);
  --shadow-xl: 0 18px 44px -14px rgba(15, 23, 42, .34);

  /* Tipografía */
  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: var(--font);

  /* Densidad: escritorio. El táctil se amplía más abajo. */
  --h-control: 36px;
  --h-control-sm: 30px;
  --fs-control: .875rem;
  --pad-pagina: 24px;
}

body.dark {
  color-scheme: dark;
  --dx-canvas: #0f111a;
  --dx-canvas-subtle: #141722;
  --dx-surface: #171a26;
  --dx-surface-raised: #1c2030;
  --dx-surface-muted: #1c2030;
  --dx-sidebar: #12141e;
  --dx-sidebar-deep: #12141e;
  --input-bg: #1c2030;
  --campo-fondo: #1c2030;
  --surface-glass: #1c2030;
  --surface-glass-hover: rgba(236, 238, 246, .06);

  --dx-text: #eceef6;
  --dx-text-secondary: #c4c9d8;
  --dx-text-muted: #acb2c6;
  --text-faint: #8a91a8;

  --dx-border: #2a2f42;
  --dx-border-strong: #3b4158;

  --dx-success: #4ade80;
  --dx-warning: #fbbf24;
  --dx-danger: #fca5a5;
  --dx-info: #7dd3fc;
  --success-soft: color-mix(in srgb, var(--dx-success) 14%, var(--bg-card));
  --warning-soft: color-mix(in srgb, var(--dx-warning) 14%, var(--bg-card));
  --danger-soft: color-mix(in srgb, var(--dx-danger) 14%, var(--bg-card));

  --dx-shadow-2: 0 14px 36px -12px rgba(0, 0, 0, .6);
  --shadow-lg: 0 14px 36px -12px rgba(0, 0, 0, .6);
  --shadow-xl: 0 20px 48px -14px rgba(0, 0, 0, .65);
}

/* Táctil (teléfono, tableta, portátil táctil): 44 px para el dedo y 16 px de
   letra en los campos, que es lo que evita el zoom automático de iOS. */
@media (pointer: coarse) {
  body {
    --h-control: 44px;
    --h-control-sm: 40px;
    --fs-control: 16px;
    --pad-pagina: 16px;
  }
}

/* ── 2. Base ──────────────────────────────────────────────────────────── */
body {
  font-family: var(--font);
  font-feature-settings: 'cv11', 'ss01';
  -webkit-font-smoothing: antialiased;
  color: var(--text-main);
  background: var(--bg-main);
  background-image: none;
}
body.dark { background-image: none; }
.main-area { background-color: var(--bg-card); }
/* Las hojas de vista previa conservan la fuente del documento (Arial, Times
   New Roman): ver la nota de la sección 6. */
/* Tampoco heredan los ajustes tipográficos de Inter (cv11, ss01): aplicados a
   Arial ensanchaban el texto de los rótulos entre 1 y 3 px respecto al PDF. */
:where(.fx-mesa, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .ea-preview, .hor-malla-preview) { font-feature-settings: normal; }
:is(h1, h2, h3, h4, h5):not(:where(.fx-mesa, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) *) { font-family: var(--font); letter-spacing: -.01em; }

/* ── 3. Barra superior ────────────────────────────────────────────────── */
body .topbar {
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.dark .topbar { background: var(--bg-card); }
body .topbar-title h2 { font-size: 1rem; font-weight: 600; color: var(--text-main); letter-spacing: -.01em; }
body .topbar-title p { font-size: .8125rem; color: var(--text-muted); }

/* Botones de ícono (ayuda, avisos, tema): todos iguales. Antes cada uno tenía
   su propio estilo, y el de ayuda se estiraba a 44 px de círculo relleno. */
body .btn-theme {
  display: inline-grid;
  place-items: center;
  width: var(--h-control);
  height: var(--h-control);
  min-width: 0;
  min-height: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  box-shadow: none;
}
body .btn-theme:hover { background: var(--bg-hover); color: var(--text-main); border-color: var(--border-strong); }
body .btn-theme svg { width: 18px; height: 18px; }
body #topbar-plan-badge {
  height: var(--h-control) !important;
  border-radius: var(--radius-sm) !important;
  background: transparent !important;
}

/* ── 4. Botones ───────────────────────────────────────────────────────────
   Tres niveles, como en AulaTrix, y los tres siguen el tema de Apariencia:
   primario (relleno del color del tema), secundario (tinte suave del tema
   con el texto en su color) y terciario (solo texto, en el color del tema).
   Uno solo primario por pantalla. Antes el secundario era un borde gris con
   texto negro: sobre los fondos cálidos de Ámbar o Terracota se perdía, y no
   se distinguía de un campo. Las acciones de generación e IA
   (.btn-generate-special) conservan su diseño propio. */
/* El color del tema como texto SOBRE su propio tinte (secundarios, menú y
   pestañas activas): un 20 % hacia el texto principal. Solo, sobre el tinte,
   Bosque, Terracota y Ámbar en claro quedaban en 4.1–4.4:1; así pasan de
   4.5:1 en las 36 combinaciones de tema, modo y nivel. En oscuro aclara. */
body { --primary-sobre-tinte: color-mix(in srgb, var(--primary-texto, var(--primary)) 80%, var(--text-main)); }
/* Relleno de los secundarios: 14 % del color del tema, más que el 9 % de
   --primary-soft (chips, filas), para que se reconozcan como botones. En
   Sobrio pasa a gris como los demás tintes (sección 22). */
body { --primary-tinte: color-mix(in srgb, var(--primary) 14%, var(--bg-card)); }
body[data-nivel="sobrio"] { --primary-tinte: var(--dx-canvas-subtle); }
body .btn {
  min-height: var(--h-control);
  padding: 0 14px;
  gap: 6px;
  border-radius: var(--radius-sm);
  font-family: var(--font);
  font-size: .875rem;
  font-weight: 600;
  line-height: 1;
  box-shadow: none;
  transition: background-color .15s, border-color .15s, color .15s;
}
body .btn:active:not(:disabled) { transform: none; }
body .btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
body .btn-primary { background: var(--primary); border-color: transparent; color: var(--primary-text, #fff); }
body .btn-primary:hover:not(:disabled) { background: var(--primary-hover); box-shadow: none; }
body :is(.btn-secondary, .btn-outline, .btn-outline-primary) { background: var(--primary-tinte); border: 1px solid transparent; color: var(--primary-sobre-tinte); }
body :is(.btn-secondary, .btn-outline, .btn-outline-primary):hover:not(:disabled) { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)); border-color: transparent; color: var(--primary-sobre-tinte); }
body .btn-ghost { background: transparent; border-color: transparent; color: var(--primary-texto, var(--primary)); }
body .btn-ghost:hover:not(:disabled) { background: var(--primary-soft); color: var(--primary-sobre-tinte); }
/* Cancelar, limpiar, volver y quitar: terciarios neutros, no compiten con la
   acción de la pantalla ni con la del diálogo. */
body :is(.btn-ghost[id^="btn-cancelar"], .ia-preview-cancel, #btn-limpiar-form, #btn-wizard-prev, #maintenance-logout, .btn-ghost[title^="Quitar"]) { color: var(--text-muted); }
body :is(.btn-ghost[id^="btn-cancelar"], .ia-preview-cancel, #btn-limpiar-form, #btn-wizard-prev, #maintenance-logout, .btn-ghost[title^="Quitar"]):hover:not(:disabled) { background: var(--bg-hover); color: var(--text-main); }
body .btn-sm { min-height: var(--h-control-sm); padding: 0 10px; font-size: .8125rem; }
body .btn:disabled { opacity: .5; cursor: not-allowed; }

/* ── 5. Campos ───────────────────────────────────────────────────────────
   Mismo alto que los botones, para que una fila de filtros o un campo con su
   botón al lado queden alineados. Van con #app porque doctrix-redesign.css
   fija alturas con #app (42 px en escritorio angosto), y style.css le pone a
   cada campo su propio --input-bg gris en tema claro: aquí se redefine sobre
   el mismo campo para que todo lo que lea esa variable vea el fondo bueno. */
body label:not(:where(.fx-mesa, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) label) { font-size: .8125rem; font-weight: 500; color: var(--text-main); }
#app :is(input[type="text"], input[type="email"], input[type="password"], input[type="date"], input[type="number"],
  input[type="time"], input[type="search"], input[type="tel"], input[type="url"], input:not([type]), select) {
  --input-bg: var(--campo-fondo);
  height: var(--h-control);
  min-height: var(--h-control);
  padding: 0 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--input-bg);
  color: var(--text-main);
  font-family: var(--font);
  font-size: var(--fs-control);
  box-shadow: none;
}
#app select { padding-right: 30px; }
#app textarea {
  --input-bg: var(--campo-fondo);
  padding: 8px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--input-bg);
  color: var(--text-main);
  font-family: var(--font);
  font-size: var(--fs-control);
  min-height: 80px;
}
body :is(input, select, textarea)::placeholder { color: var(--text-faint); }
body :is(input, select, textarea):focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
  outline: none;
}
body .input-block { margin-bottom: 12px; }
body .input-block small,
body .form-hint { font-size: .75rem; color: var(--text-muted); }

/* ── 6. Tablas ──────────────────────────────────────────────────────────────
   Solo las tablas de la aplicación. Las vistas previas de documentos (la hoja
   de Formatos y listados, la malla de horarios, la certificación, el visor de
   PDF) imitan el papel con sus propias medidas —la lista de asistencia usa
   filas de 19 px— y no deben heredar el relleno ni los tamaños de aquí: la
   vista previa dejaría de parecerse al PDF o al Word que se descarga. */
body table:not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview) table, .hor-malla-preview) { font-size: .84rem; }
body thead:not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) thead) { background: var(--bg-main); border-bottom: 1px solid var(--border); }
body th:not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) th) {
  padding: 9px 12px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--text-muted);
}
body td:not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) td) { padding: 9px 12px; border-bottom: 1px solid var(--border); }
body tbody:not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) tbody) tr:hover { background: var(--bg-hover); }

/* ── 7. Superficies ───────────────────────────────────────────────────────
   Una sola capa: sin sombras ni elevación al pasar el ratón. */
body :is(.card, .stat-card, .ge-card, .ra-card, .sace-step, .membership-summary-card, .template-service-card) {
  box-shadow: none;
  border-color: var(--border);
}
body .card { padding: 20px; border-radius: var(--radius-lg); }
body .card:hover { box-shadow: none; transform: none; border-color: var(--border); }
body .card-header { margin-bottom: 14px; padding-bottom: 12px; border-bottom-color: var(--border); }
body .card-header h3 { font-size: 1rem; font-weight: 600; }
body :is(.modal, .modal-content, .modal-box) { box-shadow: var(--shadow-xl); border-radius: var(--radius-xl); }

/* ── 8. Menú lateral ─────────────────────────────────────────────────────
   Superficie del tema, con borde a la derecha, como el resto de la app. Antes
   era azul marino siempre, también en tema claro: medio tema oscuro. */
body .sidebar {
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  box-shadow: none;
  scrollbar-color: color-mix(in srgb, var(--text-faint) 35%, transparent) transparent;
}
body .sidebar .brand-icon { background: var(--bg-card); border-color: var(--border); box-shadow: none; }
body .sidebar .brand-text h2 { color: var(--text-main); }
body .sidebar .brand-text span { color: var(--text-muted); }

body .nav-rail { border-right-color: var(--border); }
body .nav-area { color: var(--text-muted); border-radius: var(--radius-md); }
/* Tamaños de ícono del menú, en un solo sitio:
   riel 22 px (va solo, con una etiqueta de 11 px debajo) · panel, pestañas de
   Ajustes y cajón del teléfono 20 px · barra inferior 22 px · botones de la
   barra superior 18 px. Todos de trazo 2. */
body .nav-area svg { width: 22px; height: 22px; stroke-width: 2; }
body .nav-area-nombre { font-size: .75rem; }
body .sidebar .nav-panel .nav-item .nav-icon { width: 20px; height: 20px; stroke-width: 2; }
body .nav-area:hover { background: var(--bg-hover); color: var(--text-main); }
body .nav-area.active { background: color-mix(in srgb, var(--primary) 12%, var(--bg-sidebar)); color: var(--primary-sobre-tinte); }
body .nav-area-punto { box-shadow: 0 0 0 2px var(--bg-sidebar); }

body .nav-panel-cabeza { border-bottom-color: var(--border); }
body .nav-panel-cabeza strong { color: var(--text-main); }
body .nav-items { scrollbar-color: color-mix(in srgb, var(--text-faint) 35%, transparent) transparent; }
body .nav-items::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--text-faint) 35%, transparent); }
body .sidebar .nav-item { color: var(--text-muted); border-radius: var(--radius-sm); font-weight: 500; }
/* Los cinco .nav-item de las pantallas de Configuración no se listan: en su
   lugar van las pestañas (js/navegacion.js, pestanasComoItems). */
body .nav-cfg-original { display: none !important; }
body .sidebar .nav-panel button.nav-item { width: 100%; border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer; }
/* Rótulos de grupo del panel de Ajustes (Centro · Personal), js/navegacion.js. */
body .sidebar .nav-panel .nav-panel-grupo { margin: 12px 12px 4px; font-size: .75rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
body .sidebar .nav-panel .nav-panel-grupo:first-child { margin-top: 4px; }
body .sidebar .nav-item:hover { background: var(--bg-hover); color: var(--text-main); }
/* js/branding.js inyecta `.nav-item.active { color:#fff !important }`, pensado
   para el menú azul marino. Sobre la superficie clara el texto blanco
   desaparecía, así que aquí se gana por especificidad. */
body .sidebar .nav-item.active,
body .sidebar .nav-item.active > span,
body .sidebar .nav-item.active .nav-icon {
  color: var(--primary-sobre-tinte) !important;
}
body .sidebar .nav-item.active {
  background: color-mix(in srgb, var(--primary) 10%, var(--bg-card));
  border-color: transparent;
  box-shadow: none;
  font-weight: 600;
}

/* Estado del módulo (créditos, vigencia): tonos de estado del tema, ya no los
   pensados para el azul marino. */
body .nav-modulo-estado[data-tono="ok"] { background: var(--success-soft); color: var(--success); }
body .nav-modulo-estado[data-tono="aviso"] { background: var(--warning-soft); color: var(--warning); }

/* Pie: cuenta. */
body .sidebar-footer { border-top-color: var(--border); }
body #sidebar-user-name { color: var(--text-main); }
body #sidebar-user-role { color: var(--text-muted); }
body .sidebar .user-card { background: transparent; border-color: transparent; }
body .sidebar .user-card:hover { background: var(--bg-hover); }
body .sidebar .cuenta-menu {
  color: var(--text-main);
  background: var(--bg-card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
}
body .cuenta-menu-quien { border-bottom-color: var(--border); }
body .cuenta-menu-quien strong { color: var(--text-main); }
body .cuenta-menu-quien span { color: var(--text-muted); }
body .sidebar .cuenta-menu :is(button, a) { color: var(--text-main); }
/* Plan y acciones del menú de cuenta. doctrix-redesign.css les daba colores
   claros pensados para el menú azul marino (#cddcef, #ff9d96, #9fb3cf…): sobre
   este panel blanco se veían desvaídos, como deshabilitados. */
body .sidebar #sidebar-plan-badge {
  margin: 4px 0 !important;
  padding: 8px 10px !important;
  border-radius: var(--radius-sm) !important;
  background: transparent !important;
}
body .sidebar #sidebar-plan-badge:hover { background: var(--bg-hover) !important; }
body .sidebar #sidebar-plan-nombre { padding: 2px 8px; border-radius: var(--radius-sm); background: var(--warning-soft); color: var(--warning); font-size: .75rem; font-weight: 600; }
body .sidebar #sidebar-plan-badge .plan-renovar { color: var(--primary-texto, var(--primary)); font-size: .75rem; font-weight: 600; }
body .sidebar #sidebar-plan-vence { margin-top: 2px; color: var(--text-muted); font-size: .75rem; }
/* Las cuatro acciones son filas del menú, no botones sueltos: sin fondo ni
   borde propios. Antes solo se limpiaban dos; «Mi cuenta TrixHQ» y «Cerrar
   sesión en todas las apps» conservaban el fondo y el borde de .btn-logout y
   se veían como rectángulos pegados encima del menú. */
body .sidebar-footer .cuenta-menu .btn-logout {
  border-color: transparent !important;
  border-radius: var(--radius-sm) !important;
  background: transparent !important;
  font-size: .8125rem !important;
  font-weight: 500;
}
body .sidebar-footer :is(#btn-abrir-cambio-password, #enlace-mi-cuenta-trix, #btn-logout-trix) { color: var(--text-main) !important; }
body .sidebar-footer :is(#btn-abrir-cambio-password, #enlace-mi-cuenta-trix, #btn-logout-trix):hover { color: var(--text-main) !important; background: var(--bg-hover) !important; }
body .sidebar-footer #btn-logout { color: var(--danger) !important; }
body .sidebar-footer #btn-logout:hover { color: var(--danger) !important; background: var(--danger-soft) !important; }

@media (min-width: 768px) {
  /* El panel flotante de pantallas es lo único del menú que flota: lleva la
     sombra y el fondo de panel. */
  body .nav-panel { background: var(--bg-card); border-right: 1px solid var(--border); box-shadow: var(--shadow-xl); }
}

/* ── 9. Títulos de sección ────────────────────────────────────────────────
   Una etiqueta pequeña y una línea, no un título grande. js/branding.js los
   pinta con el color institucional (!important); aquí vuelven al gris: el
   color queda para lo que se pulsa. */
body .form-section-title {
  margin: 24px 0 12px;
  padding: 0 0 8px;
  border-left: 0;
  border-bottom: 1px solid var(--border);
  color: var(--text-muted) !important;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
body .form-section-title::before { content: none; }

/* ── 10. Configuración ────────────────────────────────────────────────────
   Una columna de pestañas a la izquierda y el contenido a la derecha (ver
   js/configuracion.js). Las pantallas de debajo no cambian: la columna se
   añade encima y el resto de hijos pasa a la segunda columna. */
body .page-content.active.con-config {
  display: grid;
  grid-template-columns: 188px minmax(0, 1fr);
  align-items: start;
  gap: 0 32px;
}
.cfg-contenido { grid-column: 2; display: flex; flex-direction: column; gap: 20px; min-width: 0; max-width: 960px; }
/* Operadores es una pantalla «a sangre» (.page-tabla: sin relleno, y 28 px a
   cada hijo que no es la tabla). Dentro de Configuración eso corría la columna
   de pestañas al cambiar a esa pestaña: la página recupera su relleno de
   siempre (:where, para que Cristal y Contraste sigan poniendo el suyo) y las
   dos columnas no llevan el de los hijos. */
@media (min-width: 768px) {
  .page-content.page-tabla:where(.con-config) { padding: 26px 28px 40px; }
  body .page-content.page-tabla.con-config > :is(.cfg-pestanas, .cfg-contenido) { padding: 0; }
}
.cfg-contenido > * { flex-shrink: 0; }
.cfg-pestanas {
  grid-column: 1;
  grid-row: 1;
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Misma fila que un ítem del panel del menú (ícono de 20 px, .9rem, 40 px):
   Ajustes se abre desde el riel como cualquier área y su columna en la
   pantalla repite esas mismas filas. */
.cfg-pestana {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: .875rem;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.cfg-pestana .nav-icon { flex-shrink: 0; width: 20px; height: 20px; opacity: 1; }
.cfg-pestana:hover { background: var(--bg-hover); color: var(--text-main); }
.cfg-pestana[aria-current="page"] {
  background: color-mix(in srgb, var(--primary) 10%, var(--bg-card));
  color: var(--primary-sobre-tinte);
  font-weight: 600;
}
/* Rótulos de grupo: Centro (solo el director, cambia para todos) y Personal
   (cambia solo para quien lo elige). Antes, una línea sin nombre. */
.cfg-grupo { margin: 14px 10px 4px; font-size: .75rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.cfg-grupo:first-child { margin-top: 0; }
.cfg-fuera { display: none !important; }

/* Mi Centro dentro de Configuración: sin el título que repetía la barra y
   sin la barra flotante con un segundo "Guardar" (el único sube a la barra
   superior). Conserva su tarjeta, como Mi cuenta, Operadores y las demás
   pestañas: sin ella, Unidad e Identidad eran las únicas con el formulario
   suelto sobre el fondo, y en Cristal solo le quedaba el filo de vidrio de
   arriba, una línea suelta bajo las pestañas. */
.con-config :is(.center-config-title, .center-config-footer-actions, .center-config-divider) { display: none !important; }
#page-admin-centro.con-config .center-config-header { justify-content: flex-start; margin: 0 0 4px; padding: 0 0 12px; }
#page-admin-centro.con-config .form-section-title:first-of-type,
#page-admin-centro.con-config [data-cfg-pestana]:not(.cfg-fuera) ~ .form-section-title { margin-top: 20px; }

/* Las pestañas van en una fila arriba, en todos los anchos. En tableta la
   columna de 188 px dejaba al contenido tan angosto que Formatos partía el
   texto en una palabra por renglón; y en escritorio, la columna (íconos,
   nombres y rótulos «Unidad» / «Personal») era idéntica al panel del riel:
   al abrir Documentos o Académico encima, se leían dos menús montados y la
   columna parecía un menú pegado que no se cerraba. */
@media all {
  body .page-content.active.con-config { display: flex; flex-direction: column; gap: 12px; }
  /* A todo lo ancho: la página conserva el align-items:start de la rejilla de
     escritorio y, en columna, eso encogía el contenido a lo que mide (la tabla
     de Operadores quedaba de 267 px en un teléfono de 390). */
  .cfg-contenido { max-width: none; align-self: stretch; }
  body .page-content.page-tabla.con-config > .cfg-contenido { padding-left: 0; padding-right: 0; }
  .cfg-pestanas {
    position: static;
    flex-direction: row;
    overflow-x: auto;
    gap: 4px;
    margin: 0 calc(-1 * var(--pad-pagina));
    padding: 0 var(--pad-pagina) 8px;
    border-bottom: 1px solid var(--border);
    scrollbar-width: none;
  }
  .cfg-pestanas::-webkit-scrollbar { display: none; }
  .cfg-pestana { flex: 0 0 auto; white-space: nowrap; }
  /* En la tira horizontal del teléfono el rótulo es un corte entre grupos. */
  .cfg-grupo { flex: 0 0 auto; align-self: center; margin: 0 2px 0 8px; }
  .cfg-grupo:first-child { margin-left: 0; }
}

/* Centro: la cabecera se queda vacía (su Guardar sube a la barra y la conexión
   de Drive baja a su sección), y la carpeta de Drive deja de ser un recuadro. */
#page-admin-centro.con-config .center-config-header { display: none !important; }
#page-admin-centro.con-config .drive-folder-top-block { padding: 0; border: 0; background: transparent; }
#page-admin-centro.con-config #drive-connection-container { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; }

/* ── 11. Estados vacíos ───────────────────────────────────────────────────
   Una invitación corta, no media pantalla en blanco con un ícono grande. */
body .empty-state {
  padding: 28px 16px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: transparent;
  color: var(--text-muted);
}
body .empty-state .empty-icon { width: 36px; height: 36px; margin: 0 auto 10px; border-radius: var(--radius-md); opacity: 1; filter: none; color: var(--text-muted); }
body .empty-state .empty-icon svg { width: 20px; height: 20px; }
body .empty-state h4 { margin: 0 0 4px; font-size: .875rem; font-weight: 600; }
body .empty-state p { margin: 0; font-size: .8125rem; }

/* Logo del centro: la zona para subirlo era un ícono sin tamaño de 300 px. */
#page-admin-centro .drop-zone { display: flex !important; align-items: center; gap: 10px; padding: 12px 16px !important; border: 1px dashed var(--border-strong); border-radius: var(--radius-lg); background: transparent; }
#page-admin-centro .drop-zone .drop-icon { display: grid; place-items: center; width: 32px; height: 32px; margin: 0; color: var(--text-muted); }
#page-admin-centro .drop-zone .drop-icon svg { width: 20px; height: 20px; }
#page-admin-centro .drop-zone p { margin: 0; font-size: .8125rem; color: var(--text-muted); }

/* Botones con estilos en línea de la barra (Renovar, Actualizar): secundarios,
   con el tinte del tema (sección 4). .btn-outline va con .btn-secondary. */
body :is(#topbar-btn-renovar, #topbar-btn-actualizar) {
  background: var(--primary-tinte) !important;
  border: 1px solid transparent !important;
  color: var(--primary-sobre-tinte) !important;
  border-radius: var(--radius-sm) !important;
}
body :is(#topbar-btn-renovar, #topbar-btn-actualizar):hover { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)) !important; }

/* ── 12. Inicio ───────────────────────────────────────────────────────────
   Un panel de trabajo: cifras en texto, dos listas con líneas y una fila de
   accesos. Sin tarjetas, sin chips de color y sin saludo. */
#page-inicio.active { gap: 24px; max-width: 1480px; }
.ini-cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
}
.ini-cifra { display: flex; flex-direction: column; gap: 2px; padding: 14px 18px; border-left: 1px solid var(--border); }
.ini-cifra:first-child { border-left: 0; }
.ini-cifra[hidden] { display: none; }
.ini-cifra strong { font-size: 1.25rem; font-weight: 600; line-height: 1.2; color: var(--text-main); font-variant-numeric: tabular-nums; }
.ini-cifra span { font-size: .8125rem; color: var(--text-muted); }

.ini-columnas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.ini-bloque { min-width: 0; }
.ini-bloque-cabeza { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; margin-bottom: 6px; }
.ini-bloque-cabeza h2 { margin: 0; font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }

.ini-lista { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.ini-lista > li { border-bottom: 1px solid var(--border); }
.ini-fila { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 8px 4px; }
.ini-fila-boton { width: 100%; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: var(--radius-sm); }
.ini-fila-boton:hover { background: var(--bg-hover); }
.ini-fila-boton:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.ini-fila-texto { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.ini-fila-texto strong { font-size: .875rem; font-weight: 500; color: var(--text-main); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ini-fila-texto small { font-size: .75rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ini-fila time { flex-shrink: 0; font-size: .75rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ini-fila .btn { flex-shrink: 0; }
.ini-vacio { display: flex; align-items: center; gap: 10px; padding: 16px 4px; font-size: .875rem; color: var(--text-muted); }

/* Estado como punto de color, no como pastilla. */
.ini-punto { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint, var(--text-muted)); }
.ini-punto[data-tono="aviso"] { background: var(--warning); }
.ini-punto[data-tono="info"] { background: var(--primary); }
.ini-punto[data-tono="ok"] { background: var(--success); }

.ini-accesos { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 4px; }
/* Accesos: secundarios del tema (sección 4), en píldoras pequeñas. */
.ini-accesos button {
  height: var(--h-control-sm);
  padding: 0 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: var(--primary-tinte);
  color: var(--primary-sobre-tinte);
  font: inherit;
  font-size: .8125rem;
  font-weight: 500;
  cursor: pointer;
}
.ini-accesos button:hover { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)); }
.ini-accesos button[hidden] { display: none; }

@media (max-width: 860px) {
  .ini-columnas { grid-template-columns: minmax(0, 1fr); }
  .ini-cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ini-cifra:nth-child(odd) { border-left: 0; }
  .ini-cifra:nth-child(n+3) { border-top: 1px solid var(--border); }
}
@media (pointer: coarse) {
  .ini-accesos button { height: 40px; }
}

/* ── 13. Documentos: "Míos / Todo el centro" ──────────────────────────────
   Un control segmentado: las dos listas son una sola entrada del menú. */
.dx-alcance {
  display: inline-flex;
  flex-shrink: 0;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-main);
}
.dx-alcance[hidden] { display: none; }
.dx-alcance button {
  height: calc(var(--h-control) - 6px);
  padding: 0 12px;
  border: 0;
  border-radius: calc(var(--radius-md) - 2px);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: .8125rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}
.dx-alcance button[aria-pressed="true"] { background: var(--bg-card); color: var(--text-main); box-shadow: 0 0 0 1px var(--border); }
.dx-alcance button:hover:not([aria-pressed="true"]) { color: var(--text-main); }
/* La barra de filtros reparte el ancho entre todos sus hijos (flex 1 1 150px);
   el selector mide lo que miden sus dos botones. En el teléfono ocupa la fila. */
body .operational-toolbar > .dx-alcance { flex: 0 0 auto; min-width: 0; }
.dx-alcance button { flex: 1; }
#page-admin-docs-todos .filters-container .search-bar { flex: 1; min-width: 200px; }

/* ── 14. Menú: Documentos con el plan vencido ─────────────────────────────
   El área sigue en el riel con su ícono atenuado, y su panel explica por qué
   está vacía. Atenuaba el botón entero y el nombre quedaba en 2,3:1. */
body .nav-area.nav-area-apagada svg { opacity: .45; }
body .nav-panel-nota { margin: 8px 12px 0; font-size: .8125rem; line-height: 1.45; color: var(--text-muted); }

/* Riel: los nombres "Documentos" y "Académico" no cabían. La barra mide 84 px
   y su relleno de 16 px por lado dejaba 52 px para botones de 64: todo lo que
   pasara de "Ajustes" salía cortado con puntos suspensivos. */
@media (min-width: 768px) {
  body .sidebar.sidebar-dos-niveles { padding-inline: 4px; }
  body .sidebar-dos-niveles .nav-area { width: 80px; padding-inline: 0; }
  body .sidebar.sidebar-dos-niveles { padding-inline: 2px; }
}

/* ── 15. Densidad en toda la app ──────────────────────────────────────────
   Barrido de todas las pantallas (25) buscando lo que hace que una pantalla
   se vea "suelta": títulos de 27 a 38 px en los encabezados de los módulos,
   rellenos de 25 a 36 px, íconos decorativos de 2 a 2,4 rem y estados vacíos
   con un alto mínimo fijo de 180 a 360 px aunque dijeran una sola frase.
   Una herramienta de trabajo lleva el título en la barra superior; dentro de
   la pantalla basta un encabezado de 16 px, el mismo tamaño que ese título:
   ningún texto de la pantalla es más grande que él. No toca la pantalla de entrada ni
   las hojas de vista previa. */

/* Encabezados de módulo (SACE, Rendimiento, Matrícula, Certificaciones,
   Configuración académica): un solo tamaño. */
body :is(.academic-module-hero, .ge-hero, .ra-header, .cs-header, .academic-hero) :is(h1, h2) {
  font-size: 1rem !important;
  line-height: 1.3;
  letter-spacing: -.01em;
}
/* Títulos de sección, de tarjeta y de diálogo que otras hojas dejaban en 20 a
   32 px: 16 px, como el título de la barra. */
body :is(
  .emitir-empty-template h4, .certification-validation-copy h3,
  .ea-heading h2, .ea-review-head h2,
  .ge-toolbar h2, .ge-work-header h1, .ge-import-progress-copy h3,
  .ra-document-guide strong, .academic-completion-heading h2, .sace-local-title,
  .module-package-section-head h4, .onboarding-section-heading h3,
  .payment-resolution-heading h3, .template-picker-dialog h2, .template-service-copy h3,
  .execution-confirm-balance b, .academic-editor-head h3
) {
  font-size: 1rem !important;
  line-height: 1.35;
}
/* Nota de vista previa (Personalización): usaba 10 a 13 px, bajo la escala. */
body .root-live-preview-note strong { font-size: .8125rem; }
body .root-live-preview-note :is(small, em) { font-size: .75rem; }
/* Precios y conteos de otras hojas que iban a 24 px: 20 px como las demás cifras. */
body :is(.academic-package-card > strong, .ra-package-grid article > strong, .ge-bulk-record-count strong, .template-service-meter strong) {
  font-size: 1.25rem !important;
  font-variant-numeric: tabular-nums;
}
body .ge-commercial-main h2 { font-size: 1rem; }
body .ge-commercial-hero { padding: 16px 20px; }
body :is(.ge-commercial-main, .ge-commercial-action) { padding: 20px; }
body .academic-module-state h2 { font-size: 1rem; }
body :is(.ra-card, .cs-card) { padding: 20px; }

/* Íconos decorativos: acompañan, no presiden. */
body :is(.academic-module-state > span, .academic-dropzone > span, .ra-drop span, .ge-empty span, .ge-commercial-icon, .template-picker-empty span, .template-service-empty span, .emitir-empty-template-icon) {
  font-size: 1.25rem;
}

/* Estados vacíos, de carga y de error: el alto que pide su contenido. */
body :is(.empty-state, .ge-empty) { min-height: 0; padding: 24px 16px; }
body .academic-module-state { min-height: 0; margin-block: 0; padding: 24px; }
body .academic-module-loading { min-height: 160px; }
body :is(.template-service-empty, .template-picker-empty) { min-height: 120px; }
body :is(.ge-loading) { padding: 24px; }
body :is(.academic-dropzone, .ra-drop, .academic-dropzone.ra-drop) { min-height: 132px; }
body .emitir-empty-template { padding: 16px 20px; }

/* Vacío "compacto": una línea con su ícono al lado, no un bloque centrado. */
body .empty-state.compact {
  min-height: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  text-align: left;
}
body .empty-state.compact .empty-icon { flex-shrink: 0; width: 28px; height: 28px; margin: 0; display: grid; place-items: center; font-size: .875rem; }
body .empty-state.compact h4 { margin: 0; font-size: .875rem; }
body .empty-state.compact p { margin: 0 0 0 auto; font-size: .8125rem; }
@media (max-width: 600px) {
  body .empty-state.compact { flex-wrap: wrap; }
  body .empty-state.compact p { flex-basis: 100%; margin: 0 0 0 40px; }
}

/* Cifras sueltas (root, matrícula, rendimiento): 20 px, el único tamaño por
   encima del título, y solo para números. */
body .stat-card { padding: 14px 16px; }
body .stat-value { font-size: 1.25rem; font-variant-numeric: tabular-nums; }
body :is(.ge-metric strong, .ra-detection strong) { font-size: 1.25rem; }
body #admin-plantillas-counter strong { font-size: 1.25rem; }
body .profile-security-card { margin-top: 0; }

/* ── 16. Facturación ──────────────────────────────────────────────────────
   Era la más suelta: un título de 32 px en una tarjeta de 150 px, cuatro
   fichas de 108 px separadas por huecos y "sin solicitudes" en un bloque de
   130 px. Ahora sigue el mismo patrón que Inicio: encabezado en una línea,
   cifras en una franja y secciones separadas por líneas. */
#page-admin-membresia .membership-hero {
  padding: 0 0 16px;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  gap: 16px;
}
#page-admin-membresia .membership-eyebrow { display: none; }
#page-admin-membresia .membership-title-row { margin: 0 0 4px; gap: 10px; }
#page-admin-membresia .membership-title-row h3 { font-size: 1rem; font-weight: 600; }
#page-admin-membresia .membership-hero-copy p { font-size: .875rem; line-height: 1.45; }

#page-admin-membresia .membership-summary-grid {
  gap: 0;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
}
#page-admin-membresia .membership-summary-card {
  min-height: 0;
  padding: 12px 16px;
  border: 0;
  border-left: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
}
#page-admin-membresia .membership-summary-card:first-child { border-left: 0; }
#page-admin-membresia .membership-summary-card > span { font-size: .75rem; font-weight: 600; letter-spacing: .05em; }
#page-admin-membresia .membership-summary-card strong { margin: 2px 0 0; font-size: 1.25rem; }
#page-admin-membresia .membership-summary-card small { font-size: .75rem; color: var(--text-muted); }
/* Sin sombra también: Cristal les pone la de su lámina, y sin fondo ni borde
   quedaban como franjas a medias con el título pegado al canto. */
#page-admin-membresia .card:not(.membership-hero) { padding: 0; border: 0; background: transparent; box-shadow: none; }
#page-admin-membresia .card-header { margin-bottom: 10px; padding-bottom: 8px; }
#page-admin-membresia .card-header h3 { font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
@media (max-width: 860px) {
  #page-admin-membresia .membership-summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #page-admin-membresia .membership-summary-card:nth-child(odd) { border-left: 0; }
  #page-admin-membresia .membership-summary-card:nth-child(n+3) { border-top: 1px solid var(--border); }
}

/* ── 17. Teléfono ─────────────────────────────────────────────────────────
   El cascarón del teléfono, con el patrón de AulaTrix: barra superior de una
   línea (☰ · título · campana · ayuda) con las acciones de la pantalla en una
   segunda fila; barra inferior de cuatro accesos, sólida; y un cajón a
   pantalla completa como único menú (js/menu-movil.js). Antes la barra
   superior aplastaba el título ("I", "C…") con un botón y tres íconos, la
   inferior llevaba cinco botones y se veía el contenido a través, y había
   tres menús distintos. Las pantallas en sí no cambian. */
@media (max-width: 767px) {
  body .topbar { flex-wrap: wrap; gap: 8px; padding: 8px 12px; }
  body .topbar > div:first-child { flex: 1 1 0; min-width: 0; gap: 8px !important; }
  body .topbar .topbar-actions { display: contents; }
  body .topbar #topbar-acciones-pagina { order: 10; flex: 1 0 100%; display: flex; gap: 8px; }
  body .topbar #topbar-acciones-pagina:empty { display: none; }
  body .topbar #topbar-acciones-pagina .btn { flex: 1; justify-content: center; }
  /* Las acciones de Formatos y listados esconden su nombre en el teléfono
     (js/rotulos/formatos.css, de cuando iban junto al título). En esta fila a
     lo ancho sí caben dos con nombre: con el ícono solo quedaban dos barras
     vacías («Descargar PDF», «Descargar Word» en Entrega Académica). */
  body .topbar #topbar-acciones-pagina:not(:has(> .fx-accion:nth-child(3))) .fx-accion span { display: inline; }
  /* Un "Actualizar" secundario no merece una barra a lo ancho: va a la derecha, chico. */
  body .topbar #topbar-acciones-pagina .btn-ghost:only-child { flex: 0 0 auto; margin-left: auto; }

  /* Filtros de las tablas: fecha y tipo lado a lado; búsqueda y selector a lo ancho. */
  body .page-tabla .operational-toolbar { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 10px; }
  body .page-tabla .operational-toolbar > :is(.dx-alcance, .search-bar, .btn) { grid-column: 1 / -1; }
  body .page-tabla .operational-toolbar > .btn-ghost { justify-self: end; width: auto !important; }
  /* En las filas-tarjeta de las tablas, los botones de acción también se tocan con el dedo. */
  body .page-tabla td .btn { min-height: 44px; }
  /* El tema, la salida y el plan viven en el pie del cajón; el plan vencido
     avisa además en Inicio y en la campana. */
  body .topbar :is(#btn-theme, #topbar-plan-badge) { display: none !important; }
  body .topbar-title { min-width: 0; }
  body .topbar-title h2 { font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body .topbar-title p { display: block; font-size: .75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body #btn-menu-mobile { display: inline-grid; flex-shrink: 0; }

  /* El menú lateral de escritorio no se usa en el teléfono. */
  body .sidebar, body .sidebar-backdrop { display: none !important; }

  /* Barra inferior: cuatro accesos, fondo sólido. */
  body #bottom-nav {
    display: flex;
    height: auto;
    min-height: 56px;
    padding: 4px 4px max(4px, env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body .bottom-nav-item {
    flex: 1;
    min-height: 52px;
    margin: 0;
    padding: 4px 2px;
    gap: 2px;
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
  }
  body .bottom-nav-item.active { color: var(--primary-texto, var(--primary)); background: transparent; box-shadow: none; }
  body .bnav-icon { display: grid; place-items: center; width: 28px; height: 26px; background: transparent !important; transform: none !important; }
  body .bnav-icon svg { width: 22px; height: 22px; stroke-width: 2; }
  body .bottom-nav-item.bnav-accion .bnav-icon {
    width: 40px;
    height: 40px;
    margin-top: -12px;
    border-radius: 50%;
    background: var(--primary) !important;
    color: #fff;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 35%, transparent);
  }
  body .bottom-nav-item.bnav-accion .bnav-icon svg { width: 20px; height: 20px; }
  body .bnav-badge { top: 2px; right: 14px; }
  body .page-content { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important; }

  /* Configuración: pestañas como chips deslizables, pegadas arriba. La fila
     se aplastaba a 2 px: con overflow-x:auto un hijo de flex pierde su alto
     mínimo y se encogía hasta desaparecer. */
  body .page-content.active.con-config { gap: 16px; }
  body .cfg-pestanas {
    flex: 0 0 auto;
    align-self: stretch;
    width: auto;
    max-width: none;
    position: sticky;
    top: 0;
    z-index: 5;
    margin: calc(-1 * var(--pad-pagina)) calc(-1 * var(--pad-pagina)) 0;
    padding: 8px var(--pad-pagina);
    gap: 6px;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    margin-bottom: 4px;
  }
  body .cfg-pestana {
    height: 36px;
    min-height: 0;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: .8125rem;
    line-height: 34px;
  }
  body .cfg-pestana .nav-icon { display: none; }
  body .cfg-pestana[aria-current="page"] {
    border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 10%, var(--bg-card));
    color: var(--primary-sobre-tinte);
  }

  /* Letra mínima de 12 px en lo que se lee (no en las hojas de documento). */
  body :is(small, .form-section-title, .campo-ayuda, .ge-kicker, .template-service-eyebrow, .membership-eyebrow):not(:where(.fx-mesa, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .ea-preview, .hor-malla-preview) *) { font-size: max(.75rem, 12px); }
}

/* Cajón del menú (js/menu-movil.js). Fuera del área de la app no existe. */
.menu-movil {
  position: fixed;
  inset: 0;
  z-index: 1300;
  display: flex;
  flex-direction: column;
  background: var(--bg-main);
  color: var(--text-main);
  font-family: var(--font);
}
.menu-movil[hidden] { display: none; }
@media (min-width: 768px) { .menu-movil { display: none !important; } }
body.menu-movil-abierto { overflow: hidden; }
.mm-cabeza { display: flex; align-items: center; justify-content: space-between; padding: max(12px, env(safe-area-inset-top, 0px)) 16px 8px; }
.mm-cabeza h2 { margin: 0; font-size: 1rem; font-weight: 600; }
.mm-cerrar { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-card); color: var(--danger); cursor: pointer; }
.mm-cerrar svg { width: 22px; height: 22px; }
.mm-buscar { display: flex; align-items: center; gap: 10px; height: 44px; margin: 4px 16px 12px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-card); color: var(--text-muted); }
.mm-buscar svg { flex-shrink: 0; width: 20px; height: 20px; }
.mm-buscar input {
  flex: 1;
  min-width: 0;
  height: 100% !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  color: var(--text-main);
  font: inherit;
  font-size: 1rem!important; /* con menos, iOS hace zoom al escribir */
}
.mm-buscar input::-webkit-search-cancel-button { -webkit-appearance: none; }
.mm-lista { flex: 1; display: flex; flex-direction: column; gap: 10px; padding: 0 16px 16px; overflow-y: auto; overscroll-behavior: contain; }
.mm-grupo { flex: 0 0 auto; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-card); overflow: hidden; }
.mm-grupo-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 8px 12px 8px 14px;
  border: 0;
  background: transparent;
  color: var(--text-main);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.mm-grupo-icono { flex-shrink: 0; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; background: var(--bg-main); color: var(--primary-texto, var(--primary)); }
.mm-grupo-icono svg { width: 20px; height: 20px; }
.mm-grupo-titulo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 1rem; font-weight: 600; }
.mm-grupo-estado { font-size: .75rem; font-weight: 500; color: var(--text-muted); }
.mm-grupo-estado[data-tono="aviso"] { color: var(--warning); }
.mm-grupo-estado[data-tono="ok"] { color: var(--success); }
.mm-grupo-cuenta { display: grid; place-items: center; min-width: 24px; height: 24px; padding: 0 8px; border-radius: 999px; background: var(--bg-main); color: var(--text-muted); font-size: .75rem; font-weight: 600; }
.mm-grupo-cabeza > svg { flex-shrink: 0; width: 20px; height: 20px; color: var(--text-faint); transition: transform .15s ease; }
.mm-grupo.es-abierto .mm-grupo-cabeza > svg { transform: rotate(90deg); }
.mm-grupo.es-directo.es-activa .mm-grupo-cabeza { background: color-mix(in srgb, var(--primary) 10%, var(--bg-card)); color: var(--primary-sobre-tinte); }
.mm-opciones { list-style: none; margin: 0; padding: 4px 8px 8px; border-top: 1px solid var(--border); }
.mm-opcion {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 6px 10px 6px 46px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text-main);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.mm-opcion.es-activa { background: color-mix(in srgb, var(--primary) 10%, var(--bg-card)); color: var(--primary-sobre-tinte); }
.mm-opcion .mm-opcion-icono { flex-shrink: 0; width: 20px; height: 20px; color: var(--text-muted); }
.mm-opcion.es-activa .mm-opcion-icono { color: var(--primary-sobre-tinte); }
.mm-opcion-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.mm-opcion-texto strong { font-size: .875rem; font-weight: 500; }
.mm-opcion.es-activa .mm-opcion-texto strong { font-weight: 600; }
.mm-opcion-texto small { font-size: .75rem; color: var(--text-muted); }
.mm-rotulo { margin: 10px 8px 2px; font-size: .75rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.mm-rotulo:first-child { margin-top: 6px; }
.mm-resultados { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-card); overflow: hidden; }
.mm-resultados li + li { border-top: 1px solid var(--border); }
.mm-resultados .mm-opcion { min-height: 52px; padding-left: 14px; border-radius: 0; }
.mm-resultados .mm-opcion > svg { width: 18px; height: 18px; color: var(--text-faint); }
.mm-vacio { margin: 0; padding: 24px 8px; text-align: center; color: var(--text-muted); font-size: .875rem; }
.mm-cuenta { padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--border); background: var(--bg-card); }
.mm-cuenta-quien { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.mm-cuenta-avatar { flex-shrink: 0; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--primary); color: #fff; font-weight: 600; }
.mm-cuenta-texto { display: flex; flex-direction: column; min-width: 0; }
.mm-cuenta-nombre { font-size: 1rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mm-cuenta-detalle, .mm-cuenta-plan { font-size: .75rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mm-cuenta-plan[data-tono="aviso"] { color: var(--warning); }
.mm-cuenta-acciones { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.mm-cuenta-acciones button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 56px;
  padding: 6px 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-main);
  color: var(--text-main);
  font: inherit;
  font-size: .75rem;
  font-weight: 500;
  cursor: pointer;
}
.mm-cuenta-acciones button svg { width: 20px; height: 20px; color: var(--text-muted); }
.mm-cuenta-acciones button.es-salir, .mm-cuenta-acciones button.es-salir svg { color: var(--danger); }

/* ── 18. Íconos vectoriales (js/iconos.js) ────────────────────────────────
   Un solo juego SVG de trazo para botones, avisos y estados vacíos, en lugar
   de emojis y símbolos de texto. Miden lo que mide la letra y toman su color. */
.dx-ico { display: inline-block; width: 1.1em; height: 1.1em; vertical-align: -.2em; flex-shrink: 0; }
.btn .dx-ico, button .dx-ico { margin-right: .35em; }
.btn .dx-ico:last-child, button .dx-ico:last-child { margin-right: 0; }
.btn .dx-ico:only-child, .modal-close .dx-ico, .btn-theme .dx-ico { margin: 0; }
body .empty-state .empty-icon .dx-ico { width: 20px; height: 20px; margin: 0; }
.ai-tool-icon .dx-ico, .btn-generate-icon .dx-ico, .generation-success-icon .dx-ico { margin: 0; width: 1em; height: 1em; vertical-align: -.15em; }
.emitir-empty-template-icon .dx-ico { width: 22px; height: 22px; }
.custom-select-chevron .dx-ico { width: 16px; height: 16px; vertical-align: middle; }

/* ── 19. Gestión escolar: pantalla de contratación ───────────────────────
   Antes repetía el título y la descripción de la barra superior en una
   tarjeta grande, con dos rótulos en mayúsculas, un ícono decorativo y ocho
   tamaños de letra. Ahora: qué hace el módulo a la izquierda, contratar a la
   derecha, y cuatro tamaños (20 / 14 / 13 / 12 px). */
.ge-oferta { padding: 0; }
.ge-oferta-cuerpo { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 32px; align-items: start; max-width: 1100px; }
.ge-oferta-texto h2 { margin: 0 0 8px; font-size: 1rem; font-weight: 600; line-height: 1.3; }
.ge-oferta-texto > p { margin: 0 0 20px; max-width: 60ch; font-size: .875rem; line-height: 1.5; color: var(--text-muted); }
.ge-oferta-lista { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; }
.ge-oferta-lista li { display: flex; gap: 10px; align-items: flex-start; padding: 12px 0; border-top: 1px solid var(--border); }
.ge-oferta-lista li .dx-ico { flex-shrink: 0; width: 18px; height: 18px; margin: 2px 0 0; color: var(--success); }
.ge-oferta-lista li span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ge-oferta-lista li strong { font-size: .875rem; font-weight: 600; }
.ge-oferta-lista li small { font-size: .8125rem; color: var(--text-muted); }
.ge-oferta-accion { display: flex; flex-direction: column; gap: 14px; padding: 20px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-card); }
.ge-oferta-estado { align-self: flex-start; padding: 4px 10px; border-radius: 999px; font-size: .75rem; font-weight: 600; background: var(--bg-main); color: var(--text-muted); }
.ge-oferta-estado.is-available { background: var(--success-soft); color: var(--success); }
.ge-oferta-estado.is-pending { background: color-mix(in srgb, var(--primary) 10%, var(--bg-card)); color: var(--primary-sobre-tinte); }
.ge-oferta-estado.is-warning { background: var(--warning-soft); color: var(--warning); }
.ge-oferta-centro { display: flex; flex-direction: column; gap: 2px; }
.ge-oferta-centro small { font-size: .75rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.ge-oferta-centro strong { font-size: 1rem; font-weight: 600; }
.ge-oferta-nota { display: flex; flex-direction: column; gap: 6px; }
.ge-oferta-nota span { font-size: .8125rem; font-weight: 500; }
.ge-oferta-nota textarea { width: 100%; font-size: .875rem; }
.ge-oferta-accion .ge-request-state { margin: 0; }
.ge-oferta-accion .btn-primary { width: 100%; justify-content: center; }
.ge-oferta-accion .btn-ghost { align-self: center; }
@media (max-width: 860px) {
  .ge-oferta-cuerpo { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .ge-oferta-lista { grid-template-columns: minmax(0, 1fr); }
}

.academic-hero-nota { margin: 0; font-size: .875rem; color: var(--text-muted); }

/* Solicitudes (root): el título y la descripción repetían la barra superior. */
#page-root-pagos .card-header h3, #page-root-pagos .card-header + p { display: none; }

/* ── 20. SACE y Rendimiento: tarea al centro, contexto al lado ────────────
   Antes: dos tarjetas de 118 px (créditos, Drive), una barra de compra a lo
   ancho, una tarjeta-guía de tres columnas y los pasos, todo con bordes del
   color del centro; el área de subir archivos quedaba bajo el pliegue. Ahora
   la tarea (pasos, guía en una línea, selección, resultados) ocupa la columna
   principal y el contexto —créditos, compra, informes recientes— una columna
   lateral fija de 300 px. El color del centro solo en la acción principal. */
body .academic-shell { width: 100%; }
/* Solo donde el módulo repartió sus bloques en tarea + lateral (SACE y
   Rendimiento). Sin el :has() alcanzaba a Certificaciones de Estudio, que usa
   la misma clase, y partía su formulario en dos columnas. */
body .academic-workspace:has(> .academic-tarea) {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 20px 32px;
  align-items: start;
  max-width: 1180px !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
.academic-tarea { grid-column: 1; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.academic-lateral { grid-column: 2; position: sticky; top: 0; display: flex; flex-direction: column; gap: 12px; }
body .academic-overview-grid { display: flex; flex-direction: column; gap: 12px; }
body .academic-overview-grid > .academic-balance-card,
body .academic-overview-grid > .academic-drive-card { height: auto !important; min-height: 0 !important; max-height: none !important; }

/* Créditos: una tarjeta con rótulo, saldo, detalle y su botón de compra
   dentro. Antes el saldo iba a 20 px (más grande que el título de la
   pantalla) y "Comprar" era una barra suelta a lo ancho de la columna. Ahora
   sigue la misma escala que la tarjeta de Drive que tiene al lado: rótulo de
   12 px, título de 14 px y detalle de 12 px. */
body .academic-creditos {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
}
body .academic-creditos > :is(.academic-balance-card, #sace-execution-balance) {
  display: block !important;
  height: auto !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
body .academic-balance-card .academic-balance-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body .academic-balance-card .academic-balance-main small { font-size: .75rem !important; font-weight: 600; letter-spacing: .05em; color: var(--text-muted) !important; }
body .academic-balance-card .academic-balance-main strong { font-size: .875rem !important; font-weight: 600; line-height: 1.4; color: var(--text-main) !important; }
body .academic-balance-card .academic-balance-main span { font-size: .75rem !important; line-height: 1.4; color: var(--text-muted) !important; }
body .academic-balance-card .academic-credit-equivalence { margin: 0 !important; font-size: .75rem; }
/* Comprar: botón secundario de la tarjeta (sección 4: tinte del tema), del
   alto de los controles pequeños. */
body .academic-creditos > :is(.academic-commerce-action, #ra-show-packages) {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--h-control-sm);
  margin: 0 !important;
  padding: 0 12px !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm) !important;
  background: var(--primary-tinte) !important;
  color: var(--primary-sobre-tinte) !important;
  font-size: .8125rem !important;
  font-weight: 600 !important;
  line-height: 1;
  box-shadow: none !important;
}
body .academic-creditos > :is(.academic-commerce-action, #ra-show-packages):hover { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)) !important; }
/* Descartar (revisión de SACE): secundario del tema; module-theme.css lo
   dejaba gris con un id. */
body #sace-module-container .academic-secondary-action { background: var(--primary-tinte) !important; border-color: transparent !important; color: var(--primary-sobre-tinte) !important; }
body .academic-creditos > [hidden] { display: none !important; }
body .academic-access-card { padding: 16px; border-radius: var(--radius-lg); background: var(--bg-card); }

/* Informes recientes: lista compacta. Actualizar es un botón de ícono en la
   esquina (no un botón rojo que se come una línea), y cada informe ocupa dos
   líneas —nombre y fecha— para que el nombre no se corte a los 15 caracteres. */
body :is(.academic-drive-card, .academic-overview-grid > .academic-drive-card) { padding: 14px 16px !important; border-color: var(--border) !important; border-radius: var(--radius-lg) !important; background: var(--bg-card) !important; }
body .academic-drive-heading { flex-wrap: nowrap; align-items: flex-start; justify-content: space-between; gap: 8px; }
body .academic-overview-grid > .academic-drive-card .academic-drive-heading > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body .academic-overview-grid > .academic-drive-card .academic-drive-heading > div > :is(strong, span) { overflow: visible; white-space: normal; }
body .academic-drive-heading small { font-size: .75rem; font-weight: 600; letter-spacing: .05em; color: var(--text-muted); }
body .academic-drive-heading strong { font-size: .875rem; font-weight: 600; }
body .academic-drive-heading span { font-size: .75rem; color: var(--text-muted); }
body .academic-refresh-button {
  flex-shrink: 0;
  min-height: var(--h-control-sm) !important;
  padding: 0 10px !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm) !important;
  background: var(--primary-tinte) !important;
  color: var(--primary-sobre-tinte) !important;
  font-size: .8125rem !important;
  font-weight: 600 !important;
}
body .academic-refresh-button.is-icon { width: var(--h-control-sm) !important; height: var(--h-control-sm); padding: 0 !important; border-color: transparent !important; background: var(--primary-tinte) !important; color: var(--primary-sobre-tinte) !important; }
body .academic-refresh-button:hover { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)) !important; color: var(--primary-sobre-tinte) !important; }
body .academic-refresh-button > span { display: inline-flex; }
body .academic-refresh-button .dx-ico { width: 16px; height: 16px; margin: 0; }
body .academic-overview-grid > .academic-drive-card .academic-drive-list { display: block; margin-top: 10px; max-height: 196px !important; overflow: hidden auto; }
body .academic-lateral [hidden] { display: none !important; }
body .academic-drive-list a { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1px; min-width: 0; padding: 7px 0; border-top: 1px solid var(--border); color: var(--text-main); font-size: .8125rem; text-decoration: none; }
body .academic-drive-list a:hover span { color: var(--primary-texto, var(--primary)); }
body .academic-drive-list a span { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body .academic-drive-list a span .dx-ico { width: 14px; height: 14px; margin: 0 6px 0 0; vertical-align: -2px; color: var(--text-muted); }
body .academic-drive-list a small { padding-left: 20px; font-size: .75rem; text-align: left; color: var(--text-muted); }

/* Guía del documento: una nota de una línea, no una tarjeta de tres columnas. */
body .academic-document-guide {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-main);
  font-size: .8125rem;
  color: var(--text-muted);
}
body .academic-document-guide > div:first-child { flex-direction: row; align-items: baseline; gap: 6px; }
body .academic-document-guide small { display: none; }
body .academic-document-guide strong { font-size: .8125rem; font-weight: 600; color: var(--text-main); }
body .academic-document-guide span { font-size: .8125rem; }
body .academic-route { gap: 6px; padding: 2px 8px; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--bg-card); }
body .academic-route b { font-size: .75rem; font-weight: 600; letter-spacing: .04em; color: var(--text-main); }
body .academic-route i { display: inline-flex; color: var(--text-muted); }
body .academic-route i .dx-ico { width: 14px; height: 14px; margin: 0; }
body .academic-document-guide p { flex: 1 1 100%; margin: 0; font-size: .8125rem; line-height: 1.45; }

/* El fondo del módulo es el de la página: antes rendimiento.css le ponía uno
   gris propio y se veía un panel dentro del panel. Los bloques de la tarea se
   separan solo con el gap de la columna, sin márgenes heredados. */
body #rendimiento-module-container { background: transparent !important; }
body .academic-tarea > :is(.academic-document-guide, .ra-target-partial, .academic-flow, .academic-dropzone, .ra-status, .academic-progress, .academic-primary-action, .sace-step) { margin: 0 !important; }
body .academic-tarea > .ra-status:empty,
body .academic-tarea .academic-inline-status:empty { display: none; }
body .academic-selection-stage:not([style*="none"]) { display: flex !important; flex-direction: column; gap: 16px; }
/* SACE: el paso 1 es un contenedor sin marco; antes su relleno de 18 px metía
   la zona de archivos hacia dentro respecto a la guía y los pasos. */
body #sace-module-container .academic-selection-stage { padding: 0 !important; border: 0 !important; background: transparent !important; box-shadow: none !important; }
body .academic-selection-stage > * { margin: 0 !important; }

/* Pasos: una línea sobre el fondo de la página, sin franja blanca. */
body .academic-flow { padding: 0 !important; border: 0 !important; background: transparent !important; font-size: .8125rem; }

/* Parcial: una ficha como las demás, con su relleno; antes el texto quedaba
   pegado al borde de la columna. */
body .ra-target-partial {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 240px;
  align-items: center;
  gap: 16px;
  padding: 12px 16px !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-lg) !important;
  background: var(--bg-card) !important;
}
body .ra-target-partial > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body .ra-target-partial > span strong { font-size: .875rem; font-weight: 600; }
body .ra-target-partial > span small { font-size: .8125rem; color: var(--text-muted); }
body .ra-target-partial select { width: 100%; margin: 0; }

/* Selección: la acción principal con el color del centro; lo demás neutro.
   Los botones centran su texto con flex en los dos ejes (antes "Explorar
   archivos" era display:block y el texto quedaba arriba). */
body .academic-tarea .academic-dropzone { min-height: 0 !important; padding: 14px 16px !important; border: 1px dashed var(--border-strong) !important; border-radius: var(--radius-lg) !important; background: var(--bg-card) !important; }
body .academic-tarea .academic-dropzone:hover { border-color: var(--primary) !important; background: color-mix(in srgb, var(--primary) 4%, var(--bg-card)) !important; }
body .academic-tarea .academic-dropzone > b { font-size: .875rem; font-weight: 600; }
body .academic-tarea .academic-dropzone > small { font-size: .8125rem; color: var(--text-muted); }
body .academic-tarea .academic-dropzone > em {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  min-height: var(--h-control);
  margin: 0 !important;
  padding: 0 16px !important;
  border-radius: var(--radius-sm);
  font-size: .875rem;
  font-style: normal;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}
body .academic-tarea .academic-primary-action {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  align-self: flex-end;
  width: auto !important;
  min-width: 260px;
  min-height: var(--h-control);
  padding: 0 20px !important;
  border-radius: var(--radius-sm) !important;
  font-size: .875rem !important;
  font-weight: 600 !important;
  line-height: 1;
  box-shadow: none !important;
}
body .academic-tarea .academic-primary-action[style*="display:none"],
body .academic-tarea .academic-primary-action[style*="display: none"] { display: none !important; }
/* Deshabilitado: gris neutro, no el rojo desvaído al 45 % de opacidad. */
body .academic-tarea .academic-primary-action:disabled {
  opacity: 1 !important;
  border: 1px solid var(--border) !important;
  background: var(--bg-main) !important;
  color: var(--text-faint) !important;
  cursor: not-allowed;
}

@media (max-width: 960px) {
  body .academic-workspace:has(> .academic-tarea) { grid-template-columns: minmax(0, 1fr); }
  .academic-lateral { grid-column: 1; position: static; }
  body .ra-target-partial { grid-template-columns: minmax(0, 1fr); }
  body .academic-tarea .academic-primary-action { align-self: stretch; }
}

/* ── 21. Apariencia de cada persona: paletas ─────────────────────────────
   Ajustes → Apariencia (js/apariencia.js). data-tema en <body> cambia
   superficies, textos y bordes; el color primario lo pone js/branding.js con
   los datos de js/apariencia-temas.js. Sin data-tema es "Institucional": los
   grises de arriba y el color del centro. Valores de AulaTrix
   (src/app/theme/themes.css), con el mismo contraste AA.
   Claro va con :not(.dark) para no pisar el modo oscuro, que tiene la misma
   especificidad y va antes. */
body[data-tema] {
  --dx-surface-raised: var(--dx-surface);
  --dx-surface-muted: var(--dx-canvas);
  --dx-sidebar: var(--dx-canvas);
  --dx-sidebar-deep: var(--dx-canvas);
  --input-bg: var(--dx-surface);
  --campo-fondo: var(--dx-surface);
  --surface-glass: var(--dx-canvas);
  --dx-text-secondary: color-mix(in srgb, var(--dx-text) 55%, var(--dx-text-muted));
  --dx-border-strong: color-mix(in srgb, var(--dx-border) 84%, var(--dx-text));
}
body:not(.dark)[data-tema="turquesa"] {
  --dx-canvas: #f3f8fa; --dx-canvas-subtle: #e9f2f6; --dx-surface: #ffffff; --dx-border: #d6e2e8;
  --dx-text: #10232c; --dx-text-muted: #4a5f69; --text-faint: #5d717b;
}
body:not(.dark)[data-tema="indigo"] {
  --dx-canvas: #f5f6fb; --dx-canvas-subtle: #f0f2fa; --dx-surface: #ffffff; --dx-border: #e2e5f0;
  --dx-text: #171b2c; --dx-text-muted: #525970; --text-faint: #676e85;
}
body:not(.dark)[data-tema="bosque"] {
  --dx-canvas: #faf7f0; --dx-canvas-subtle: #f5f1e7; --dx-surface: #ffffff; --dx-border: #e4dece;
  --dx-text: #1c241e; --dx-text-muted: #505e54; --text-faint: #657168;
}
body:not(.dark)[data-tema="terracota"] {
  --dx-canvas: #fff7ed; --dx-canvas-subtle: #faf0e4; --dx-surface: #fffcf7; --dx-border: #eedec9;
  --dx-text: #261c14; --dx-text-muted: #6b543f; --text-faint: #806a54;
}
body:not(.dark)[data-tema="ambar"] {
  --dx-canvas: #f6f5f1; --dx-canvas-subtle: #edebe5; --dx-surface: #fffffd; --dx-border: #dddad0;
  --dx-text: #1e1d1a; --dx-text-muted: #5d5950; --text-faint: #726e63;
}
body:not(.dark)[data-tema="lavanda"] {
  --dx-canvas: #f7f5ff; --dx-canvas-subtle: #f1eaf8; --dx-surface: #ffffff; --dx-border: #d8bfd8;
  --dx-text: #1e1530; --dx-text-muted: #5b4e6e; --text-faint: #6e6283;
}
/* Oscuro: los textos que una paleta no define son los del oscuro general. */
body.dark[data-tema="turquesa"] {
  --dx-canvas: #0b151a; --dx-canvas-subtle: #16262e; --dx-surface: #111e24; --dx-border: #27404b;
}
body.dark[data-tema="indigo"] {
  --dx-canvas: #0f111a; --dx-canvas-subtle: #202434; --dx-surface: #181b28; --dx-border: #30354a;
}
body.dark[data-tema="bosque"] {
  --dx-canvas: #0c1812; --dx-canvas-subtle: #1a2e24; --dx-surface: #13241c; --dx-border: #2a4638;
}
body.dark[data-tema="terracota"] {
  --dx-canvas: #1a1410; --dx-canvas-subtle: #30261e; --dx-surface: #261e18; --dx-border: #403228;
  --dx-text: #f5eee6; --dx-text-muted: #c4b2a0; --text-faint: #968472;
}
body.dark[data-tema="ambar"] {
  --dx-canvas: #151513; --dx-canvas-subtle: #292925; --dx-surface: #1f1f1c; --dx-border: #3a3a34;
  --dx-text: #edebe4; --dx-text-muted: #b2afa4; --text-faint: #939085;
}
body.dark[data-tema="lavanda"] {
  --dx-canvas: #150f1f; --dx-canvas-subtle: #2a2040; --dx-surface: #1f1730; --dx-border: #3d2f57;
  --dx-text: #eee8f7; --dx-text-muted: #b9adcc; --text-faint: #8f82a6;
}

/* ── 22. Nivel de color: Sobrio · Marca · Completo ───────────────────────
   data-nivel en <body>. "Marca" es el de siempre y no redefine nada. */

/* Sobrio: los tintes del color pasan a gris; quedan con color los botones,
   los enlaces y los estados. La opción activa del menú, gris con una raya del
   color del tema. --primary-soft va en línea (js/branding.js): el !important
   de una hoja le gana. */
body[data-nivel="sobrio"] { --primary-soft: var(--dx-canvas-subtle) !important; }
body[data-nivel="sobrio"] :is(.nav-area.active, .sidebar .nav-item.active, .cfg-pestana[aria-current="page"], .mm-opcion.es-activa, .mm-grupo.es-directo.es-activa .mm-grupo-cabeza) {
  background: var(--dx-canvas-subtle) !important;
  box-shadow: inset 3px 0 0 var(--primary) !important;
}
body[data-nivel="sobrio"] :is(.nav-area.active, .cfg-pestana[aria-current="page"], .mm-opcion.es-activa, .mm-opcion.es-activa .mm-opcion-icono, .mm-grupo.es-directo.es-activa .mm-grupo-cabeza),
body[data-nivel="sobrio"] .sidebar :is(.nav-item.active, .nav-item.active > span, .nav-item.active .nav-icon) {
  color: var(--text-main) !important;
}
body[data-nivel="sobrio"] .bottom-nav-item.active { color: var(--text-main); }

/* Completo: el menú lateral del color del tema. El texto usa --primary-text
   (blanco u oscuro según el contraste que calcula js/branding.js), así se lee
   con cualquier color institucional; la opción activa es una pastilla de ese
   color con el primario encima. En el teléfono, la barra inferior.
   Solo en Clásico (sin data-estilo), como en EduTrix: Suave, Cristal y
   Contraste tienen su propio menú (transparente, de vidrio o negro) y estas
   reglas les dejaban los nombres en blanco sobre fondo claro. */
@media (min-width: 768px) {
  body[data-nivel="completo"]:not([data-estilo]) .sidebar { background: var(--primary); border-right-color: var(--primary); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .nav-area { color: var(--primary-text); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .nav-area:not(.active):hover { background: color-mix(in srgb, var(--primary-text) 14%, transparent); color: var(--primary-text); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .nav-area.active { background: var(--primary-text); color: var(--primary); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .nav-area-punto { box-shadow: 0 0 0 2px var(--primary); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .brand-icon { border-color: transparent; }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar-footer { border-top-color: color-mix(in srgb, var(--primary-text) 22%, transparent); }
  body[data-nivel="completo"]:not([data-estilo]) .sidebar .user-card:hover { background: color-mix(in srgb, var(--primary-text) 14%, transparent); }
}
@media (max-width: 767px) {
  body[data-nivel="completo"]:not([data-estilo]) #bottom-nav { background: var(--primary); border-top-color: var(--primary); }
  body[data-nivel="completo"]:not([data-estilo]) .bottom-nav-item { color: color-mix(in srgb, var(--primary-text) 78%, transparent); }
  body[data-nivel="completo"]:not([data-estilo]) .bottom-nav-item.active { color: var(--primary-text); font-weight: 600; }
}

/* Identidad (centro y root): el aviso de "estás con otra paleta" y el color
   del texto como opción avanzada, plegada. */
.identidad-aviso-tema {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 12px 0 0;
  padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--dx-info) 30%, var(--border));
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--dx-info) 7%, var(--bg-card));
  font-size: .8125rem;
  line-height: 1.45;
  color: var(--text-main);
}
.identidad-aviso-tema[hidden] { display: none; }
.identidad-aviso-tema .btn { flex-shrink: 0; }
@media (max-width: 600px) { .identidad-aviso-tema { flex-direction: column; align-items: stretch; } }
body .center-appearance-controls { display: flex; flex-direction: column; gap: 12px; }
.identidad-avanzado { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-card); }
.identidad-avanzado > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--h-control);
  padding: 0 12px;
  font-size: .8125rem;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
}
.identidad-avanzado > summary::-webkit-details-marker { display: none; }
.identidad-avanzado > summary::before { content: ""; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform .15s; }
.identidad-avanzado[open] > summary::before { transform: rotate(45deg); }
.identidad-avanzado > summary:hover { color: var(--text-main); }
body .identidad-avanzado .center-text-color-settings { display: grid; gap: 12px; height: auto; padding: 0 12px 12px; border: 0; background: transparent; }
body .identidad-avanzado .center-text-color-settings .input-block { margin: 0; }

/* ── 23. Pantalla Apariencia ─────────────────────────────────────────────
   Tres bloques como los de AulaTrix: tarjetas de paleta, un control
   segmentado para el nivel y tres botones para el modo. */
.ap-pantalla { display: flex; flex-direction: column; gap: 16px; max-width: 880px; }
.ap-bloque { padding: 16px 20px 20px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-card); }
.ap-bloque > header { margin-bottom: 14px; }
.ap-bloque h3 { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.35; color: var(--text-main); }
.ap-bloque > header p { margin: 2px 0 0; font-size: .875rem; color: var(--text-muted); }

.ap-temas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.ap-tema {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text-main);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.ap-tema:hover { background: var(--bg-hover); }
.ap-tema[aria-checked="true"] { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.ap-tema:focus-visible, .ap-segmentos button:focus-visible, .ap-modos button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Enlace a Identidad (director y root): de dónde sale el color Institucional. */
.ap-identidad { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 12px 0 0; padding-top: 12px; border-top: 1px solid var(--border); font-size: .8125rem; color: var(--text-muted); }
.ap-identidad .btn { flex-shrink: 0; }
@media (max-width: 600px) { .ap-identidad { flex-direction: column; align-items: flex-start; } }
.ap-tema-check {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--primary-text);
}
.ap-tema-check svg { width: 13px; height: 13px; }
.ap-muestras { display: flex; gap: 6px; margin-bottom: 8px; }
.ap-muestras span { width: 24px; height: 24px; border-radius: 999px; border: 1px solid rgba(0, 0, 0, .06); }
.ap-tema strong { font-size: .875rem; font-weight: 600; }
.ap-tema small { font-size: .75rem; line-height: 1.4; color: var(--text-muted); }

.ap-segmentos { display: inline-flex; gap: 2px; padding: 4px; border-radius: var(--radius-md); background: var(--dx-canvas-subtle); }
.ap-segmentos button {
  min-height: var(--h-control);
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: .875rem;
  font-weight: 600;
  cursor: pointer;
}
.ap-segmentos button:hover { color: var(--text-main); }
.ap-segmentos button[aria-checked="true"] { background: var(--primary); color: var(--primary-text); }
.ap-nota { margin: 10px 0 0; font-size: .8125rem; line-height: 1.45; color: var(--text-muted); }

.ap-modos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.ap-modos button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text-muted);
  font: inherit;
  font-size: .875rem;
  font-weight: 500;
  cursor: pointer;
}
.ap-modos button:hover { background: var(--bg-hover); }
.ap-modos button svg { width: 20px; height: 20px; }
.ap-modos button[aria-checked="true"] { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-sobre-tinte); }

@media (max-width: 600px) {
  .ap-bloque { padding: 14px 16px 16px; }
  .ap-temas { grid-template-columns: minmax(0, 1fr); }
  .ap-segmentos { display: flex; }
  .ap-segmentos button { flex: 1; padding: 0 8px; }
}

/* ── 24. Fase 0 del plan UX (docs/PLAN-UX-VISUAL-2026-09-30.md) ───────────
   Avisos que no tapan nada, avatar con el color del tema y botones de solo
   ícono en la barra de página. */

/* Toast: arriba a la derecha, bajo la barra superior. Abajo a la derecha tapaba
   el pie de los diálogos (el botón "Siguiente" del asistente, "Guardar"…), que
   es justo donde la persona está a punto de pulsar. En el teléfono también va
   arriba: los diálogos son hojas inferiores y el pie es lo que se toca. */
#toast-container {
  top: 68px;
  bottom: auto;
  right: 1.5rem;
}
@media (max-width: 767px) {
  #toast-container {
    top: calc(env(safe-area-inset-top, 0px) + 8px);
    bottom: auto;
    left: 12px;
    right: 12px;
  }
}

/* Avatar: el color del tema, no un naranja fijo. */
body .sidebar .user-avatar,
body .mm-cuenta-avatar {
  background: var(--primary);
  color: var(--primary-text, #fff);
}
body[data-nivel="completo"] .sidebar .user-avatar { background: var(--primary-text, #fff); color: var(--primary); }

/* Botón de solo ícono en la barra de página (p. ej. actualizar la lista). */
body .btn[data-solo-icono] { width: var(--h-control); padding: 0; justify-content: center; flex: 0 0 auto; }
body .btn[data-solo-icono] svg { margin: 0; width: 18px; height: 18px; }

/* ── 25. Lista de activación (Inicio) ─────────────────────────────────────
   Lo que falta para poder emitir, con su avance. Vive en Inicio y no bloquea:
   el asistente inicial se puede cerrar con "Configurar después". */
.ini-activacion {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
}
.ini-activacion[hidden] { display: none; }
.ini-act-cabeza { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ini-act-cabeza h2 { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.35; }
.ini-act-cabeza p { margin: 2px 0 0; font-size: .8125rem; color: var(--text-muted); }
.ini-act-barra { height: 6px; border-radius: 999px; background: var(--dx-canvas-subtle); overflow: hidden; }
.ini-act-barra i { display: block; height: 100%; width: 0; border-radius: inherit; background: var(--primary); transition: width .2s ease; }
.ini-act-pasos { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.ini-act-paso { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.ini-act-marca { flex: 0 0 28px; width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%; background: var(--primary-tinte); color: var(--primary-sobre-tinte); font-size: .8125rem; font-weight: 600; }
.ini-act-marca svg { width: 16px; height: 16px; margin: 0; }
.ini-act-paso.es-listo .ini-act-marca { background: var(--success-soft); color: var(--success); }
.ini-act-ok { flex-shrink: 0; font-size: .75rem; font-weight: 600; color: var(--success); }
.ini-act-paso .btn { flex-shrink: 0; }

/* Pie del asistente: Atrás a la izquierda; "Configurar después" y "Siguiente" juntos a la derecha. */
#modal-onboarding-wizard .modal-footer #btn-onboarding-prev { order: 0; }
#modal-onboarding-wizard .modal-footer #btn-onboarding-despues { order: 1; margin-left: auto; margin-right: 12px; }
#modal-onboarding-wizard .modal-footer #btn-onboarding-next { order: 2; }
#modal-onboarding-wizard .modal-footer #btn-onboarding-despues[hidden] { display: none; }
.ini-act-paso .ini-fila-texto small { white-space: normal; overflow: visible; text-overflow: clip; }

/* ── 26. Fase 2: tokens, cascarón y panel del menú ────────────────────────
   Tokens de espacio, tamaño de letra y movimiento (los tamaños ya estaban en
   uso; aquí tienen nombre para no escribir números sueltos en pantallas
   nuevas), barra superior de 56 px, panel del riel sin desplazamiento
   horizontal y con íconos legibles, esqueletos de carga y densidad. */
body {
  --fs-12: .75rem; --fs-13: .8125rem; --fs-14: .875rem; --fs-16: 1rem; --fs-20: 1.25rem;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
  --dur-1: 120ms; --dur-2: 200ms; --dur-3: 320ms;
  --ease: cubic-bezier(.2, .8, .2, 1);
  --h-fila: 44px;
  --pad-celda: 9px 12px;
}

/* Movimiento: solo para orientar o confirmar, y nada si la persona lo pidió. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Barra superior: 56 px, título y subtítulo en una línea con puntos suspensivos
   (el subtítulo de SACE ocupaba dos y agrandaba la barra), acciones sin encoger. */
body .topbar { min-height: 56px; padding: 8px 24px; gap: 12px; }
body .topbar > div:first-child { min-width: 0; flex: 1 1 0; }
body .topbar-title { min-width: 0; }
body .topbar-title :is(h2, p) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body .topbar-title p { margin-top: 1px; }
body .topbar-actions { flex-shrink: 0; }
/* Entre teléfono y portátil (768–1100 px) el chip del plan no cabe con los dos
   botones: queda "Renovar", y "Mejorar plan" sigue en el menú de la cuenta. */
@media (min-width: 768px) and (max-width: 1100px) {
  body #topbar-btn-actualizar { display: none !important; }
}

/* Panel del riel: íconos visibles (doctrix-redesign.css los pintaba blancos en
   768–1199 px para el menú azul de antes, y sobre el panel claro no se veían),
   sin el tooltip de barra angosta que hacía crecer el panel hacia la derecha
   (de ahí la barra de desplazamiento horizontal) y un poco más estrecho. */
body .sidebar .nav-panel .nav-item .nav-icon { color: currentColor !important; opacity: 1; }
body .sidebar .nav-panel .nav-item.active .nav-icon { color: var(--primary-sobre-tinte) !important; }
body[data-nivel="sobrio"] .sidebar .nav-panel .nav-item.active .nav-icon { color: var(--text-main) !important; }
body .sidebar .nav-panel .nav-item::after,
body .sidebar .nav-panel .nav-item[data-tooltip]::after { content: none !important; display: none !important; }
body .sidebar .nav-panel { overflow-x: hidden; }
@media (min-width: 768px) {
  body .sidebar .nav-panel { width: 252px; }
  body .sidebar .cuenta-menu { width: 252px; }
}

/* Esqueletos de carga: la forma de lo que viene en lugar de "—" y "Cargando…"
   (entre 1 y 10 s son mejores que un spinner; NN/g). Solo con aria-busy. */
@keyframes dx-brillo { to { background-position: -200% 0; } }
.skeleton,
.ini-cifras[aria-busy="true"] .ini-cifra strong {
  color: transparent !important;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--dx-canvas-subtle) 25%, color-mix(in srgb, var(--dx-canvas-subtle) 55%, var(--bg-card)) 50%, var(--dx-canvas-subtle) 75%);
  background-size: 200% 100%;
  animation: dx-brillo 1.3s linear infinite;
  user-select: none;
}
.ini-cifras[aria-busy="true"] .ini-cifra strong { display: block; width: 3.5ch; min-height: 1.5rem; }
.ini-lista[aria-busy="true"] > li.ini-vacio {
  position: relative;
  min-height: 52px;
  color: transparent;
}
.ini-lista[aria-busy="true"] > li.ini-vacio::after {
  content: "";
  position: absolute;
  inset: 14px 4px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--dx-canvas-subtle) 25%, color-mix(in srgb, var(--dx-canvas-subtle) 55%, var(--bg-card)) 50%, var(--dx-canvas-subtle) 75%);
  background-size: 200% 100%;
  animation: dx-brillo 1.3s linear infinite;
}

/* Densidad compacta (Ajustes › Apariencia). Solo con puntero fino: en una
   pantalla táctil los objetivos de 44 px no se negocian (WCAG 2.5.8). */
@media (pointer: fine) {
  body[data-densidad="compacta"] {
    --h-control: 32px;
    --h-control-sm: 28px;
    --h-fila: 36px;
    --pad-celda: 6px 10px;
    --pad-pagina: 20px;
  }
  body[data-densidad="compacta"] :is(td, th):not(:where(.fx-hoja, .la-paper, .cs-preview, .visor-pdf-hojas, .tpl-mini-hoja, .la-att-pdf-preview, .ea-preview, .hor-malla-preview) *) { padding: var(--pad-celda); }
  body[data-densidad="compacta"] .ini-fila { min-height: 44px; }
  body[data-densidad="compacta"] .nav-item { min-height: 36px; }
}
body .topbar-title h2 { line-height: 1.25; }
body .topbar-title p { line-height: 1.3; }

/* ── 27. Fase 3: catálogo de formatos y Mi cuenta ─────────────────────────
   Catálogo: tarjetas planas del sistema en lugar de degradados azul-violeta con
   sombra y seis botones llamativos; "Activar" es un secundario del tema (el
   primario queda para la confirmación del diálogo). Mi cuenta: los datos de
   solo lectura se ven como datos, no como campos que invitan a escribir. */
body .template-service-shell { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
body .template-service-intro { padding: 16px 20px; border-color: var(--border); border-radius: var(--radius-lg); background: var(--bg-card); }
body .template-service-eyebrow { margin-bottom: 4px; color: var(--text-muted); font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
body .template-service-copy h3 { font-size: 1rem; font-weight: 600; }
body .template-service-copy p { font-size: .875rem; }
body .template-service-meter { min-height: 0; padding: 12px 16px; border-radius: var(--radius-md); }
body .template-service-meter span { font-size: .75rem; font-weight: 600; letter-spacing: .05em; }
body .template-service-meter strong { font-size: 1.25rem; font-weight: 600; color: var(--text-main); }
body .template-service-toolbar strong { font-size: 1rem; font-weight: 600; }
body .template-service-grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
body .template-service-card { min-height: 0; padding: 16px; border-radius: var(--radius-lg); background: var(--bg-card); box-shadow: none; transition: border-color .15s; }
body .template-service-card:hover { transform: none; box-shadow: none; border-color: var(--border-strong); }
body .template-service-card.is-active { background: var(--bg-card); border-color: color-mix(in srgb, var(--primary) 55%, var(--border)); box-shadow: none; }
body .template-selected-mark { display: none; }
body .template-service-icon { border-radius: var(--radius-md); background: var(--primary-tinte); color: var(--primary-sobre-tinte); }
body .template-service-status { padding: 3px 8px; font-size: .75rem; font-weight: 600; letter-spacing: 0; text-transform: none; background: var(--dx-canvas-subtle); color: var(--text-muted); }
body .template-service-status.is-active { margin-right: 0; background: var(--success-soft); color: var(--success); }
body .template-service-card-copy h4 { font-size: .9375rem; font-weight: 600; text-transform: none; }
body .template-service-card-copy p { font-size: .8125rem; margin-bottom: 14px; }
body .catalog-template-action { min-height: var(--h-control); padding: 0 12px; border-radius: var(--radius-sm); font-size: .875rem; font-weight: 600; box-shadow: none; transform: none; }
body .catalog-template-action:not(:disabled):hover { transform: none; box-shadow: none; }
body .catalog-template-action.can-unlock,
body .catalog-template-action.upgrade-plan { background: var(--primary-tinte); color: var(--primary-sobre-tinte); border: 1px solid transparent; box-shadow: none; }
body .catalog-template-action.can-unlock:hover,
body .catalog-template-action.upgrade-plan:hover { background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)); }
body .catalog-template-action.upgrade-plan > span:first-child { background: transparent; color: inherit; width: 20px; height: 20px; flex-basis: 20px; }
body .catalog-template-action.upgrade-plan small { color: inherit; opacity: .8; }
body .catalog-template-state { min-height: 0; padding: 8px 12px; border-radius: var(--radius-sm); border-color: var(--border); background: transparent; }
body .catalog-template-state > span { width: 22px; height: 22px; flex-basis: 22px; border-radius: 50%; background: var(--success); }
body .catalog-template-state strong { font-weight: 600; }

/* Mi cuenta: valores de solo lectura como texto. */
body .profile-account-data .profile-info-value {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text-main);
  font-size: .9375rem;
  font-weight: 500;
}
body .profile-account-data .input-block { margin-bottom: 0; padding: 12px 0; border-bottom: 1px solid var(--border); }
body .profile-account-data .input-block:last-child { border-bottom: 0; }
body .profile-account-data .input-block > label { margin-bottom: 2px; color: var(--text-muted); font-size: .75rem; font-weight: 500; }

/* ── 28. Fase 3: accesos de Inicio y tablas de documentos ─────────────────
   Accesos: tarjetas con ícono y una línea de lo que hace cada módulo (antes,
   píldoras con solo el nombre y media pantalla en blanco debajo). */
body .ini-accesos { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; padding-top: 0; }
body .ini-accesos button {
  display: flex;
  align-items: center;
  gap: 12px;
  height: auto;
  min-height: 60px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text-main);
  text-align: left;
  transition: border-color .15s, background-color .15s;
}
body .ini-accesos button:hover { background: var(--bg-hover); border-color: var(--border-strong); }
body .ini-accesos button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.ini-acceso-ico { flex: 0 0 36px; width: 36px; height: 36px; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--primary-tinte); color: var(--primary-sobre-tinte); }
.ini-acceso-ico svg { width: 20px; height: 20px; }
body .ini-accesos .ini-fila-texto strong { font-size: .875rem; font-weight: 600; }
body .ini-accesos .ini-fila-texto small { white-space: normal; font-size: .8125rem; }

/* Tablas de documentos (escritorio): cabecera fija al desplazar, número de
   documento en tipografía de ancho fijo y acciones secundarias que aparecen al
   pasar el ratón por la fila (con teclado o pantalla táctil siempre se ven). */
@media (min-width: 768px) {
  body .page-tabla .table-wrap { max-height: calc(100dvh - 250px); overflow: auto; }
  body .page-tabla .table-wrap thead th { position: sticky; top: 0; z-index: 2; background: var(--bg-main); box-shadow: 0 1px 0 var(--border); }
  body .page-tabla .td-nomen { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8125rem; font-variant-numeric: tabular-nums; }
  body .page-tabla td time { font-variant-numeric: tabular-nums; white-space: nowrap; }
}
@media (pointer: fine) {
  body .page-tabla tbody tr .table-row-action-group > :not(:first-child) { opacity: 0; transition: opacity .12s; }
  body .page-tabla tbody tr:hover .table-row-action-group > *,
  body .page-tabla tbody tr:focus-within .table-row-action-group > * { opacity: 1; }
}
@media (min-width: 768px) {
  body .page-tabla .table-row-action-group { display: flex; flex-wrap: nowrap; gap: 4px; white-space: nowrap; }
  body .page-tabla .table-row-action-group .btn { min-height: var(--h-control-sm); padding: 0 10px; font-size: .8125rem; }
}

/* ── 29. Fase 4: Constructor de Horarios en el sistema ────────────────────
   Sin cabecera propia (el título ya está en la barra superior), botones de
   Excel como secundarios del tema en lugar de verdes, grupos de herramientas
   sin marco y un solo estilo de pasos (número · nombre) como en SACE y
   Rendimiento. */
body .horarios-workspace { border-radius: var(--radius-lg); box-shadow: none; }
body .horarios-header { padding: 12px 16px; align-items: center; }
body .horarios-header > div:first-child { display: none; }
body .horarios-file-actions { gap: 8px 12px; }
body .horarios-toolbar-group { gap: 6px; padding: 0; border: 0; border-radius: 0; background: transparent; }
body .horarios-file-actions > span { color: var(--success); font-weight: 600; }
body .btn-excel { background: var(--primary-tinte); color: var(--primary-sobre-tinte); border: 1px solid transparent; }
body .btn-excel:hover { filter: none; background: color-mix(in srgb, var(--primary) 8%, var(--primary-tinte)); }

body .horarios-steps { background: var(--bg-card); }
body .horarios-steps button {
  flex-direction: row;
  gap: 8px;
  padding: 10px 6px;
  border-right: 0;
  font-size: .8125rem;
  font-weight: 600;
  transition: background-color .15s, color .15s;
}
body .horarios-steps button > span { width: 22px; height: 22px; margin: 0; box-shadow: none; background: var(--dx-canvas-subtle); }
body .horarios-steps button > small {
  position: absolute;
  width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
body .horarios-steps button.is-ready > span,
body .horarios-steps button.is-ready.is-active > span { box-shadow: none; }
body .horarios-steps button.is-active { background: transparent; }
body .horarios-steps button.is-active > span { background: var(--primary); color: var(--primary-text, #fff); box-shadow: none; }
body .horarios-steps button.is-ready.is-active > span { background: var(--success); }
body #horarios-content { padding: 16px 20px; }
body .hor-step-intro p { font-size: .875rem; }
/* La marca de "paso listo" usaba una máscara con una medida inválida ("70%25"):
   el navegador la descartaba y en lugar del check quedaba un círculo blanco. */
body .horarios-steps button.is-ready > span::after {
  background: var(--primary-text, #fff);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 68% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 68% no-repeat;
}

/* ── 30. Fase 5: paleta de búsqueda (Ctrl+K) y atajos ─────────────────────
   js/paleta.js. Una capa sobre la app, centrada arriba como en las
   herramientas de escritorio; en el teléfono no se usa (el cajón del menú
   trae el mismo buscador). */
body.paleta-abierta { overflow: hidden; }
.paleta {
  position: fixed;
  inset: 0;
  z-index: 1400;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh 16px 16px;
  background: color-mix(in srgb, #0b1020 42%, transparent);
}
.paleta[hidden] { display: none; }
.paleta-caja {
  width: min(600px, 100%);
  max-height: min(520px, 76vh);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--bg-card);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  animation: dx-paleta-in .14s var(--ease, ease-out);
}
@keyframes dx-paleta-in { from { opacity: 0; transform: translateY(-6px) scale(.985); } }
.paleta-buscar { display: flex; align-items: center; gap: 10px; padding: 0 16px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
.paleta-buscar .dx-ico { width: 20px; height: 20px; margin: 0; }
#app .paleta-buscar input, .paleta-buscar input {
  flex: 1;
  height: 52px;
  min-height: 52px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text-main);
  font-size: 1rem;
}
.paleta-buscar input:focus { box-shadow: none; border: 0; }
.paleta kbd {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--bg-main);
  color: var(--text-muted);
  font: 600 .75rem/1 var(--font);
}
.paleta-lista { list-style: none; margin: 0; padding: 6px; overflow-y: auto; }
.paleta-op { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 6px 10px; border-radius: var(--radius-md); cursor: pointer; }
.paleta-op.es-activa { background: color-mix(in srgb, var(--primary) 10%, var(--bg-card)); }
.paleta-ico { flex: 0 0 32px; width: 32px; height: 32px; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--dx-canvas-subtle); color: var(--text-muted); }
.paleta-op.es-activa .paleta-ico { background: var(--primary-tinte); color: var(--primary-sobre-tinte); }
.paleta-ico svg { width: 18px; height: 18px; margin: 0; }
.paleta-texto { display: flex; flex-direction: column; min-width: 0; }
.paleta-texto strong { font-size: .875rem; font-weight: 600; color: var(--text-main); }
.paleta-texto small { font-size: .75rem; color: var(--text-muted); }
.paleta-vacio { padding: 24px 12px; text-align: center; font-size: .875rem; color: var(--text-muted); }
.paleta-pie { display: flex; gap: 16px; margin: 0; padding: 8px 16px; border-top: 1px solid var(--border); background: var(--bg-main); font-size: .75rem; color: var(--text-muted); }
.paleta-pie span { display: inline-flex; align-items: center; gap: 4px; }
.paleta-atajos { padding: 16px 20px 20px; }
.paleta-atajos header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.paleta-atajos h2 { margin: 0; font-size: 1rem; font-weight: 600; }
.paleta-atajos dl { margin: 0; }
.paleta-atajos dl > div { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 0; border-top: 1px solid var(--border); }
.paleta-atajos dt { display: flex; gap: 4px; }
.paleta-atajos dd { margin: 0; font-size: .875rem; color: var(--text-main); }
.paleta-atajos p { margin: 12px 0 0; font-size: .8125rem; color: var(--text-muted); }
@media (max-width: 767px) { #btn-paleta { display: none; } .paleta { padding-top: 8vh; } }


/* ── 32. Emitir: "Generar documento" siempre a la vista ───────────────────
   El formulario es largo (datos + redacción + firma): el botón principal se
   quedaba al final y había que desplazarse para encontrarlo. En escritorio la
   barra de acciones queda pegada al borde inferior mientras se escribe. */
@media (min-width: 768px) {
  body #page-emitir .document-generation-actions {
    position: sticky;
    bottom: 0;
    z-index: 4;
    margin: 16px -4px 0;
    padding: 12px 4px;
    border-top: 1px solid var(--border);
    background: var(--bg-card);
  }
}

/* ── 33. Entrar con la Cuenta Trix («correo primero») ──────────────────────
   Un solo campo de correo y «Continuar»: con cuenta TrixHQ se va a TrixHQ; si
   no, aparece la contraseña. «Usar otro correo» vuelve al primer paso, y al
   pie queda «¿Usas TrixHQ con otro correo?» como enlace, no como botón. */
.login-otro-correo { background: none; border: 0; padding: 0; margin-top: var(--sp-2); font: inherit; font-size: .875rem; cursor: pointer; }
.login-trix-otro { text-align: center; font-size: .875rem; color: var(--text-muted); margin: var(--sp-4) 0 var(--sp-3); }
.login-trix-otro .login-support { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }

/* ── 34. «Tus apps» de TrixHQ en el menú de cuenta ─────────────────────────
   Las otras apps (EduTrix, AulaTrix) entran sin volver a escribir la
   contraseña; «Mi cuenta TrixHQ» abre cuenta.trixhq.com. Los colores salen
   del propio menú (currentColor), así sirve en claro y en oscuro. */
.cuenta-menu-apps {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 0 6px;
  margin-bottom: 4px;
  border-bottom: 1px solid color-mix(in srgb, currentColor 14%, transparent);
}
.cuenta-menu-apps-titulo {
  padding: 6px 10px 2px;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: color-mix(in srgb, currentColor 62%, transparent);
}
.cuenta-menu-app {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 4px 10px;
  border-radius: 10px;
  color: inherit;
  text-decoration: none;
}
.cuenta-menu-app[hidden],
.cuenta-menu-apps-titulo[hidden] { display: none; }
.cuenta-menu-app:hover,
.cuenta-menu-app:focus-visible { background: color-mix(in srgb, currentColor 7%, transparent); }
.cuenta-menu-app span { display: flex; flex-direction: column; line-height: 1.2; font-size: .8125rem; font-weight: 600; }
.cuenta-menu-app small { font-size: .6875rem; font-weight: 400; color: color-mix(in srgb, currentColor 60%, transparent); }
.cuenta-menu-app-letra {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 9px;
  color: #fff;
  font-size: .8125rem;
  font-weight: 800;
}
.cuenta-menu-app-letra.edutrix { background: linear-gradient(135deg, #d6249f, #5b4bdb); }
.cuenta-menu-app-letra.aulatrix { background: linear-gradient(135deg, #0b7ea8, #0e9f8f); }
a.btn-logout { display: flex; align-items: center; gap: 8px; text-decoration: none; }
#btn-logout-trix span { text-align: left; }

/* ── 35. Buscar alumno en EduTrix (Constancia de Matrícula) ────────────────
   Solo aparece si el colegio tiene EduTrix + Documentos (js/alumnos-edutrix.js). */
.edutrix-buscador { position: relative; margin-bottom: var(--sp-3); }
.edutrix-buscador label { display: block; font-size: .8125rem; font-weight: 600; margin-bottom: 4px; }
.edutrix-buscador label small { font-weight: 400; color: var(--text-muted); margin-left: 4px; }
.edutrix-buscador input { width: 100%; max-width: 420px; }
.edutrix-resultados {
  list-style: none;
  margin: 4px 0 0;
  padding: 4px;
  max-width: 420px;
  border: 1px solid var(--border, #d8e0ea);
  border-radius: 10px;
  background: var(--surface, #fff);
  box-shadow: 0 8px 24px -12px rgb(15 39 66 / .35);
}
.edutrix-resultados button {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  min-height: 44px;
  padding: 6px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.edutrix-resultados button:hover,
.edutrix-resultados button:focus-visible { background: color-mix(in srgb, currentColor 7%, transparent); }
.edutrix-resultados button span { font-size: .75rem; color: var(--text-muted); }
.edutrix-resultados .vacio { padding: 8px 10px; font-size: .8125rem; color: var(--text-muted); }

/* Oculto por atributo (sin style en línea): formulario de enlace con DocTrix y «Usar otro correo». */
#login-form-propio[hidden], #btn-otro-correo[hidden] { display: none; }
/* El formulario propio aparece bajo «Entrar con TrixHQ»: su primer rótulo
   quedaba pegado al botón. */
#login-form-propio { margin-top: 20px; }
/* El body del teléfono deja abajo el sitio de la barra inferior; en la
   entrada no hay barra y quedaba una franja gris al final de la página. */
body:has(> #login-screen:not([style*="none"])) { padding-bottom: 0 !important; }
.form-hint-modal { margin: 0 0 .75rem; color: var(--text-muted); font-size: .85rem; }

/* Botones de fila de tabla: el flex va en un contenedor, nunca en el td (rompe la línea de la fila). */
.celda-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* Unidades departamentales: casilla de plantillas y modal de cargos (sin estilos en línea). */
.pl-tipo-opcion { cursor: pointer; justify-content: flex-start; }
.cargo-tipos { display: grid; gap: var(--sp-2, 8px); margin-top: 6px; }
.cargo-tipo { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: .875rem; }
.cargo-registro { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; font-size: .875rem; margin: var(--sp-3, 12px) 0 var(--sp-2, 8px); padding: .7rem; background: var(--bg-hover); border-radius: 8px; }
.cargo-ayuda { font-size: .75rem; color: var(--text-muted); margin: 0 0 1rem; }

/* Root › Clientes › Código: cambiar el código de cada centro de un cliente. */
.modal-codigo-centro { max-width: 560px; }
.codigo-centro-ayuda { font-size: .8125rem; color: var(--text-muted); margin: 0 0 var(--sp-3, 12px); }
.codigo-centro-lista { display: grid; gap: var(--sp-3, 12px); }
.codigo-centro-fila { display: flex; flex-wrap: wrap; gap: var(--sp-2, 8px); align-items: center; }
.codigo-centro-nombre { display: grid; min-width: 0; flex: 1 1 200px; }
.codigo-centro-nombre strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.codigo-centro-input { flex: 0 1 160px; font-family: monospace; letter-spacing: 1px; text-transform: uppercase; }
.codigo-centro-vacio { color: var(--text-muted); }

/* Root › Cargos: el bloque del correlativo compartido solo aparece si hay cargo superior.
   Lleva clase y no `style` inline a propósito: `elemento.hidden = true` solo vale el
   `display:none` del navegador, y un `display:flex` escrito en el atributo le ganaría. */
.cargo-registro[hidden], .cargo-ayuda[hidden] { display: none !important; }

/* Root › Reglas de nomenclatura (js/reglas-nomenclatura-ui.js) */
.modal-regla { max-width: 640px; }
.regla-patron, .regla-ejemplo { font-family: monospace; font-size: .8125rem; padding: 2px 6px; border-radius: 4px; background: var(--surface-glass); overflow-wrap: anywhere; }
.regla-ejemplo { color: var(--primary-texto, var(--primary)); }
.regla-patron-input { font-family: monospace; letter-spacing: .5px; }
.regla-variables { display: grid; gap: var(--sp-2, 8px); margin: 0 0 var(--sp-3, 12px); }
.regla-variables-grupo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.regla-variables-grupo > span { flex: 0 0 100%; font-size: .75rem; color: var(--text-muted); }
.regla-variable { font-family: monospace; font-size: .75rem; padding: 4px 8px; min-height: 32px; border: 1px solid var(--border); border-radius: 6px; background: var(--input-bg); color: var(--text-main); cursor: pointer; }
.regla-variable:hover, .regla-variable:focus-visible { border-color: var(--primary); color: var(--primary-texto, var(--primary)); }
.regla-vista-previa { border: 1px solid var(--border); border-radius: 10px; padding: var(--sp-3, 12px); margin: 0 0 var(--sp-3, 12px); }
.regla-vista-previa legend { font-size: .8125rem; font-weight: 700; padding: 0 6px; }
.regla-prev-resultado { display: block; font-family: monospace; font-size: 1rem; font-weight: 700; padding: .6rem .8rem; border-radius: 8px; background: var(--bg-hover); overflow-wrap: anywhere; }
.regla-prev-problemas { margin: 8px 0 0; padding-left: 1.2rem; color: var(--danger); font-size: .8125rem; }
.regla-prev-problemas[hidden] { display: none !important; }
.root-reglas-table .fila-separador td { font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); background: var(--bg-hover); }
#cent-codigo-container[hidden], #cent-siglas-unidad-container[hidden], #regla-centro-bloque[hidden] { display: none !important; }

/* ── Configuración › Formatos: cada formato vuelve a ser una tarjeta ──────────────────────────
   La «superficie plana» (doctrix-redesign.css y la sección 7 de este archivo) quitó borde y fondo
   a todas las tarjetas. En esta pantalla eso las borró: sobre el fondo blanco los formatos se veían
   como texto suelto, con un ícono diminuto, y un formato activo no se distinguía de uno disponible.
   Todo va acotado a #page-admin-plantillas: ninguna otra pantalla cambia. */
#page-admin-plantillas .template-service-card {
  position: relative;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-card);
  transition: border-color .15s, box-shadow .15s;
}
#page-admin-plantillas .template-service-card:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--border)); box-shadow: 0 4px 14px color-mix(in srgb, var(--primary) 10%, transparent); }
/* Activo: borde y fondo del color de la institución, y la marca de seleccionado en la esquina. */
#page-admin-plantillas .template-service-card.is-active {
  border: 2px solid var(--primary);
  padding: 17px;
  background: linear-gradient(160deg, color-mix(in srgb, var(--primary) 9%, var(--bg-card)), var(--bg-card) 60%);
}
#page-admin-plantillas .template-service-card.is-active .template-selected-mark {
  display: grid; place-items: center;
  position: absolute; top: 0; right: 0; width: 34px; height: 34px; padding: 0 0 6px 6px;
  border-radius: 0 12px 0 14px; color: #fff; background: var(--primary);
}
#page-admin-plantillas .template-selected-mark .dx-ico { width: 16px; height: 16px; margin: 0; }
/* Con la marca, la etiqueta «Activo» de arriba sobraba (y quedaba debajo de la marca). */
#page-admin-plantillas .template-service-status.is-active { display: none; }
#page-admin-plantillas .template-service-icon { width: 48px; height: 48px; border-radius: 12px; }
#page-admin-plantillas .template-service-icon .dx-ico { width: 24px; height: 24px; margin: 0; }
#page-admin-plantillas .template-service-card-copy h4 { font-size: 1rem; }
/* Root › Cargos: «+ Nuevo Cargo» crea solo cargos principales y esconde «Depende del cargo». */
#cargo-padre-bloque[hidden] { display: none !important; }

/* ── Root › Cargos Institucionales: organigrama por tipo de institución ────────────────────────
   Antes era una tabla de siete columnas con todos los tipos mezclados y cuatro botones por fila.
   Ahora: una pestaña por tipo, cada cargo principal es una tarjeta con sus coordinaciones dentro,
   y por cargo solo lo que importa (nombre, siglas en el número, con quién numera). */
#page-root-cargos .cargos-barra { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
#page-root-cargos .cargos-pestanas { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px; border-radius: 12px; background: var(--bg-hover); }
#page-root-cargos .cargos-pestana { white-space: nowrap; display: inline-flex; align-items: center; gap: 8px; min-height: 38px; padding: 0 14px; border: 0; border-radius: 9px; background: transparent; color: var(--text-muted); font: inherit; font-size: .875rem; font-weight: 600; cursor: pointer; }
#page-root-cargos .cargos-pestana span { min-width: 22px; padding: 1px 7px; border-radius: 999px; background: var(--bg-card); font-size: .75rem; }
#page-root-cargos .cargos-pestana.is-activa { background: var(--bg-card); color: var(--text-main); box-shadow: 0 1px 3px rgba(0,0,0,.08); }
#page-root-cargos .cargos-pestana.is-activa span { background: var(--primary); color: #fff; }
/* «Mostrar desactivados» y «Plegar todas» comparten la misma fila: el botón es texto del mismo
   tamaño, sin relleno vertical, para que la barra no crezca. */
#page-root-cargos .cargos-barra-fin { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; }
#page-root-cargos .cargos-plegar-todas { display: inline-flex; align-items: center; gap: 5px; padding: 0; border: 0; background: none; color: var(--primary-texto, var(--text-main)); font: inherit; font-size: .8125rem; font-weight: 600; line-height: 1.4; cursor: pointer; }
#page-root-cargos .cargos-plegar-todas[hidden] { display: none; }
#page-root-cargos .cargos-plegar-todas:hover { text-decoration: underline; text-underline-offset: 3px; }
#page-root-cargos .cargos-plegar-todas svg { width: 14px; height: 14px; flex: 0 0 auto; }
/* En el teléfono «Mostrar desactivados» ocupa casi todo el ancho: el botón queda solo con su
   ícono (su nombre va en aria-label y title) para no bajar a otro renglón. */
@media (max-width: 767px) {
  #page-root-cargos .cargos-barra-fin { flex-wrap: nowrap; gap: 8px; }
  #page-root-cargos .cargos-plegar-todas { flex: 0 0 auto; justify-content: center; width: 40px; height: 40px; border: 1px solid var(--border); border-radius: 12px; }
  #page-root-cargos .cargos-plegar-todas span { display: none; }
  #page-root-cargos .cargos-plegar-todas svg { width: 18px; height: 18px; }
}
#page-root-cargos .cargos-inactivos { display: inline-flex; align-items: center; gap: 6px; font-size: .8125rem; color: var(--text-muted); cursor: pointer; }
#page-root-cargos .cargos-ayuda { margin: 0 0 16px; font-size: .875rem; color: var(--text-muted); line-height: 1.5; }
#page-root-cargos .cargos-ayuda b { color: var(--text-main); font-family: monospace; }

#page-root-cargos .cargos-grupos { display: grid; gap: 12px; }
#page-root-cargos .cargo-grupo { border: 1px solid var(--border); border-radius: 14px; background: var(--bg-card); overflow: visible; }
#page-root-cargos .cargo-grupo.tiene-hijos > .cargo-fila:first-child { border-bottom: 1px solid var(--border); }
#page-root-cargos .cargo-fila { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px 14px calc(16px + var(--nivel, 0) * 24px); }
#page-root-cargos .cargo-hijos { padding: 4px 0; background: color-mix(in srgb, var(--primary) 3%, var(--bg-card)); border-radius: 0 0 14px 14px; }
#page-root-cargos .cargo-hijos .cargo-fila { position: relative; padding-top: 10px; padding-bottom: 10px; }
#page-root-cargos .cargo-hijos .cargo-fila::before { content: ''; position: absolute; left: calc(var(--nivel, 1) * 24px); top: 0; bottom: 50%; width: 12px; border-left: 2px solid color-mix(in srgb, var(--primary) 35%, var(--border)); border-bottom: 2px solid color-mix(in srgb, var(--primary) 35%, var(--border)); border-bottom-left-radius: 6px; }
#page-root-cargos .cargo-fila.is-inactivo { opacity: .55; }
#page-root-cargos .cargo-fila-texto { min-width: 0; display: grid; gap: 6px; }
#page-root-cargos .cargo-fila-texto strong { font-size: .9375rem; color: var(--text-main); }
#page-root-cargos .cargo-fila-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
#page-root-cargos .cargo-fila-meta code { padding: 2px 8px; border-radius: 6px; background: var(--bg-hover); color: var(--primary-texto, var(--primary)); font-size: .8125rem; font-weight: 700; }
#page-root-cargos .cargo-etiqueta { padding: 2px 8px; border-radius: 999px; background: var(--bg-hover); color: var(--text-muted); font-size: .75rem; }
#page-root-cargos .cargo-etiqueta.es-inactivo { background: var(--warning-soft, #fff4e5); color: var(--warning, #b45309); }
#page-root-cargos .cargo-fila-acciones { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
#page-root-cargos .cargo-agregar { display: block; width: 100%; padding: 12px 16px; border: 0; border-top: 1px dashed var(--border); border-radius: 0 0 14px 14px; background: transparent; color: var(--primary-texto, var(--primary)); font: inherit; font-size: .875rem; font-weight: 600; text-align: left; cursor: pointer; }
#page-root-cargos .cargo-agregar:hover { background: color-mix(in srgb, var(--primary) 6%, transparent); }
#page-root-cargos .cargo-menu { position: relative; }
#page-root-cargos .cargo-menu summary { list-style: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 8px; color: var(--text-muted); font-size: 1.1rem; cursor: pointer; }
#page-root-cargos .cargo-menu summary::-webkit-details-marker { display: none; }
#page-root-cargos .cargo-menu summary:hover, #page-root-cargos .cargo-menu[open] summary { background: var(--bg-hover); color: var(--text-main); }
#page-root-cargos .cargo-menu-lista { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 160px; padding: 4px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-card); box-shadow: 0 8px 24px rgba(0,0,0,.12); }
#page-root-cargos .cargo-menu-lista button { display: block; width: 100%; padding: 8px 12px; border: 0; border-radius: 6px; background: transparent; color: var(--text-main); font: inherit; font-size: .875rem; text-align: left; cursor: pointer; }
#page-root-cargos .cargo-menu-lista button:hover { background: var(--bg-hover); }
#page-root-cargos .cargo-menu-lista .es-peligro { color: var(--danger); }
@media (max-width: 640px) {
  #page-root-cargos .cargo-fila { flex-wrap: wrap; }
  /* Una sola línea que se desliza de lado: partidas en dos renglones, las palabras se cortaban. */
  #page-root-cargos .cargos-pestanas { width: 100%; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  #page-root-cargos .cargos-pestanas::-webkit-scrollbar { display: none; }
  #page-root-cargos .cargos-pestana { flex: 0 0 auto; white-space: nowrap; }
}

/* Formulario de cargo, por secciones y con vista previa. */
/* En la computadora hay espacio: el formulario se ensancha y el número entra completo. */
#modal-cargo .modal-cargo-form { max-width: 760px; }
#modal-cargo .cargo-seccion { margin: 0 0 16px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; }
#modal-cargo .cargo-seccion h4 { margin: 0 0 10px; font-size: .8125rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
#modal-cargo .cargo-seccion .input-block:last-of-type { margin-bottom: 8px; }
#modal-cargo .cargo-avanzado summary { font-size: .875rem; font-weight: 600; cursor: pointer; }
#modal-cargo .cargo-avanzado[open] summary { margin-bottom: 10px; }
#modal-cargo .cargo-vista { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 10px; margin-top: 4px; }
#modal-cargo .cargo-vista > div { padding: 10px 12px; border-radius: 10px; background: var(--bg-hover); }
#modal-cargo .cargo-vista > div > span { display: block; margin-bottom: 6px; font-size: .6875rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
#modal-cargo .cargo-vista-firma { margin: 0; font-size: .75rem; line-height: 1.5; text-align: center; color: var(--text-muted); }
#modal-cargo .cargo-vista-firma strong { color: var(--text-main); }
#modal-cargo .cargo-vista code { display: block; font-size: .9375rem; font-weight: 700; color: var(--primary-texto, var(--primary)); overflow-wrap: anywhere; }
@media (max-width: 520px) { #modal-cargo .cargo-vista { grid-template-columns: 1fr; } }

/* Plantillas NMC: acciones. Los botones habían quedado sin ícono (se quitaron
   los emojis y no se pusieron los SVG), y como Editar, Duplicar y Drive son
   btn-ghost —fondo y borde transparentes— no se veían: solo asomaban los dos
   con borde de color. Ahora todos llevan ícono y borde, y van alineados a la
   izquierda bajo la cabecera «Acciones» en lugar de flotar a la derecha. */
#tabla-plantillas-wrap .btn-icono { display: inline-flex; align-items: center; justify-content: center; }
#tabla-plantillas-wrap .btn-icono .dx-ico { width: 18px; height: 18px; margin: 0; }
#tabla-plantillas-wrap .btn-icono.btn-ghost { border: 1px solid var(--border); color: var(--text-main); }
#tabla-plantillas-wrap .btn-icono.btn-ghost:hover:not(:disabled) { border-color: var(--primary); color: var(--primary-texto, var(--primary)); }
@media (min-width: 1241px) {
  #tabla-plantillas-wrap .template-actions-cell .cell-flex-wrap { justify-content: flex-start; }
}

/* Renovación: una unidad, un distrito o una dirección municipal solo tienen un
   plan (ver planesDeTipo en js/tipos-institucion.js); su tarjeta ocupa la fila
   en vez de quedar a media anchura junto a un hueco. */
.renewal-modal #pricing-cards-container > .pricing-card:only-child { grid-column: 1 / -1; }

/* Cargos: plegar una unidad con sus coordinaciones. La flecha va antes del
   nombre; plegada, la unidad muestra cuántas tiene y esconde la lista y el
   «+ Agregar coordinación». */
#page-root-cargos .cargo-fila-texto { flex: 1 1 auto; }
#page-root-cargos .cargo-plegar { flex: 0 0 32px; display: grid; place-items: center; width: 32px; height: 32px; margin: 0 -4px 0 -6px; padding: 0; border: 0; border-radius: 999px; background: transparent; color: var(--text-muted); cursor: pointer; transition: background-color .15s, color .15s; }
#page-root-cargos .cargo-plegar:hover { background: var(--bg-hover); color: var(--text-main); }
#page-root-cargos .cargo-plegar:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
#page-root-cargos .cargo-plegar svg { width: 18px; height: 18px; transition: transform .18s ease; }
#page-root-cargos .cargo-grupo.is-plegado .cargo-plegar svg { transform: rotate(-90deg); }
#page-root-cargos .cargo-grupo.is-plegado > :is(.cargo-hijos, .cargo-agregar) { display: none; }
#page-root-cargos .cargo-grupo.is-plegado > .cargo-fila:first-child { border-bottom: 0; }
#page-root-cargos .cargo-etiqueta.cargo-cuenta { display: none; }
#page-root-cargos .cargo-grupo.is-plegado .cargo-etiqueta.cargo-cuenta { display: inline-block; }
@media (prefers-reduced-motion: reduce) { #page-root-cargos .cargo-plegar svg { transition: none; } }
@media (max-width: 640px) {
  /* La flecha al lado del nombre (con el renglón partido quedaba sola arriba). */
  #page-root-cargos .cargo-fila:has(> .cargo-plegar) { display: grid; grid-template-columns: 32px minmax(0, 1fr); align-items: start; column-gap: 8px; }
  #page-root-cargos .cargo-fila:has(> .cargo-plegar) > .cargo-plegar { margin: -4px 0 0 -6px; }
  #page-root-cargos .cargo-fila:has(> .cargo-plegar) > .cargo-fila-acciones { grid-column: 2; }
}

/* ── 34. Emitir: el número del documento en creación ──────────────────────
   El renglón pequeño de la tarjeta de la plantilla dice «Próximo N.º …» en
   vez de «PLANTILLA SELECCIONADA»: ocupa el mismo sitio, así que no suma
   altura. El número va en monoespaciada, como en la lista de documentos. */
.template-select-premium small.tsp-numero { display: block; overflow: hidden; letter-spacing: 0; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.template-select-premium small.tsp-numero em { font-style: normal; }
.template-select-premium small.tsp-numero span { display: inline !important; margin-left: 3px; color: var(--primary-texto, var(--text-main)); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 700; font-variant-numeric: tabular-nums; }
/* En el teléfono el número largo (CONS-039-080100456M12-2026-DCE-JM) no cabía
   con la etiqueta y se cortaba: va solo el número, que el título de la tarjeta
   explica al tocarla. */
@media (max-width: 767px) {
  .template-select-premium small.tsp-numero em { display: none; }
  .template-select-premium small.tsp-numero span { margin-left: 0; font-size: .6875rem; letter-spacing: -.01em; }
}
@media (max-width: 380px) {
  .template-select-premium small.tsp-numero span { font-size: .65rem; letter-spacing: -.02em; }
}

/* Confirmación: con qué número sale el documento, mirado al abrirla. Si
   cambió desde que se abrió el formulario, un aviso arriba lo dice. */
.confirm-numero { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.confirm-numero-aviso { margin: 0 0 10px; padding: 9px 12px; border: 1px solid color-mix(in srgb, var(--warning) 35%, transparent); border-radius: var(--radius-md); background: var(--warning-soft); color: var(--text-main); font-size: .8125rem; line-height: 1.45; }
.confirm-numero-nota { margin: 6px 0 0; color: var(--text-muted); font-size: .75rem; line-height: 1.45; }
