/* Paquete estructura — corrección del frontend 13-sep-2026 (docs/auditoria/frontend-vistas-2026-09-13.md).
 *
 * Cromo común: menú móvil, barra superior en pantallas estrechas, buscador,
 * desplegables de avisos y pie legal. Va detrás de cyberconquer.css y usa sus
 * tokens (--accent, --line, --bg-1…). */

/* ══════════════════════════════════════════════════════════════════════════
   BOTÓN SECUNDARIO DEL TEMA (DCC-01)
   ══════════════════════════════════════════════════════════════════════════
   material-dashboard.css trae `.btn.btn-outline-secondary{color:#333;
   border-color:#333}`: pensado para fondo claro. Medido en /team/update sobre el
   fondo oscuro: rgb(51,51,51) contra rgb(9,12,17), contraste 1.55:1 — «Cancelar»
   parecía deshabilitado. Se había parcheado pantalla a pantalla (insignia, aviso
   de equipo) y cada botón nuevo volvía a salir ilegible. Se corrige una vez, con
   la especificidad de la regla de origen, para todo el frontend. */
.btn.btn-outline-secondary,
.btn.btn-outline-secondary.disabled,
.btn.btn-outline-secondary:disabled {
  color: var(--fg-dim);
  border-color: var(--line-bright);
  background-color: transparent;
}
.btn.btn-outline-secondary:hover,
.btn.btn-outline-secondary:focus,
.btn.btn-outline-secondary:focus-visible,
.btn.btn-outline-secondary:not(:disabled):not(.disabled):active {
  color: var(--fg);
  border-color: var(--line-bright);
  background-color: var(--bg-2);
}

/* ══════════════════════════════════════════════════════════════════════════
   FICHA DE USUARIO DE LA BARRA LATERAL (DCC-03)
   ══════════════════════════════════════════════════════════════════════════
   Nombre y rango son <span> en línea dentro de .user-meta: medido, el rango
   empezaba en la MISMA línea que el nombre («alumnoux2 Sin» / «clasificar»).
   Cada uno en su renglón y el rango sin partir. */
.user-card .user-name,
.user-card .user-rank { display: block; }
.user-card .user-rank { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ══════════════════════════════════════════════════════════════════════════
   MENÚ MÓVIL (EST-01, EST-02)
   ══════════════════════════════════════════════════════════════════════════ */

/* Visible solo donde la barra lateral es panel deslizante. Antes el botón
   llevaba `d-lg-none` (<992px) y la barra solo desliza por debajo de 760px:
   entre 761 y 991 el botón metía el contenido bajo la barra fija. */
.cc-solo-movil { display: none !important; }
@media (max-width: 760px) {
  .cc-solo-movil { display: grid !important; }
}

/* El panel principal NUNCA se desplaza. material-dashboard.css trae
   `.nav-open .main-panel{transform:translate3d(-260px,0,0)}`, pensado para un
   menú que entraba por la derecha: medido a 390px, el contenido se iba 260px a
   la izquierda y dejaba una franja vacía. Con la barra entrando por la
   izquierda sobre el contenido, no hay nada que mover. */
html.nav-open .main-panel,
html.nav-open .cc-app > .main {
  transform: none !important;
  left: auto !important;
}

/* Capa de cierre: cuelga de <body> (material-dashboard.js) y cubre la ventana
   entera por debajo de la barra (z-index 1050, fijado en academia-ux.js).
   Antes vivía dentro del panel transformado y quedaba en x=-260. */
.close-layer {
  position: fixed !important;
  inset: 0;
  width: auto; height: auto;
  z-index: 1040;
  background: oklch(0 0 0 / 0.55);
  opacity: 1;
  cursor: pointer;
}

/* Botón «Cerrar menú» dentro de la barra, arriba a la derecha de la marca. */
.brand-block { position: relative; }
.cc-cerrar-menu {
  position: absolute;
  top: 12px; right: 12px;
  width: 44px; height: 44px;
}

/* Botón de entregar bandera dentro de su grupo, a cualquier ancho.
   material-dashboard.css trae `.navbar-form .btn{position:absolute;top:-5px;
   right:-50px}` (el formulario flotaba en la navbar heredada), y la vista claim
   conserva la clase navbar-form. Medido a 390px: el botón salía en x=379..427,
   fuera de una pantalla de 390, y 5px más arriba que el campo. */
.topbar .claim .navbar-form .btn {
  position: static !important;
  top: auto; right: auto;
}

/* ══════════════════════════════════════════════════════════════════════════
   BARRA SUPERIOR EN PANTALLA ESTRECHA (FIC-02, RET-12, AYU-17, EST-10)
   ══════════════════════════════════════════════════════════════════════════
   Medido a 390px: el campo de bandera [76..196] y su botón [202..246] quedaban
   debajo del botón del rayo (~182-220), el placeholder se cortaba («entrega una
   ba») y la miga también («Re1», «Trivia ( fundamer»). Todo cabía en una sola
   fila de 60px que no da para tanto. En móvil la barra pasa a dos filas: arriba
   la vuelta atrás y los botones; abajo la entrega de banderas a todo el ancho. */
@media (max-width: 760px) {
  .topbar {
    flex-wrap: wrap;
    height: auto !important;
    min-height: 60px;
    padding: 8px 12px !important;
    row-gap: 8px;
    column-gap: 8px;
  }
  .topbar > * { max-height: none; }

  /* Fila 1: la miga padre ocupa el espacio libre y los botones se alinean a la
     derecha con su área táctil de 44px. */
  .topbar .breadcrumbs { order: 1; flex: 1 1 0; min-width: 0; overflow: hidden; flex-wrap: nowrap; }
  .topbar .icon-btn,
  .topbar .dropdown { order: 2; }
  .topbar .icon-btn { width: 44px; height: 44px; }
  .topbar .navbar-toggler { order: 3; }

  /* Fila 2: la entrega de banderas, sola y a todo el ancho. */
  .topbar .claim {
    order: 10;
    flex: 1 1 100%;
    min-width: 0;
    max-height: none;
  }
  /* El <form class="navbar-form"> de la vista claim no se estiraba: medido, el
     grupo acababa en x=306 de 390 y el botón quedaba 5px más arriba que el
     campo. Formulario y grupo a todo el ancho, alineados por estiramiento. */
  .topbar .claim form,
  .topbar .claim .navbar-form { display: block; width: 100%; margin: 0; padding: 0; }
  .topbar .claim .input-group { width: 100%; max-height: none; align-items: stretch; }
  .topbar .claim .form-control {
    flex: 1 1 auto; width: auto !important; max-width: none; min-width: 0;
    height: 44px; min-height: 44px; line-height: 44px;
  }
  .topbar .claim .btn,
  .topbar .claim .btn-just-icon { width: 48px; height: 44px; min-height: 44px; }

  /* Migas: solo el padre inmediato, como «‹ Máquinas» (EST-10). Antes quedaba
     únicamente la miga actual, que es texto: en una ficha no había vuelta atrás.
     La miga actual sobra, el h1 de la página ya la dice. */
  .topbar .breadcrumbs > * { display: none; }
  .topbar .breadcrumbs > .miga-padre {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--fg-dim);
  }
  .topbar .breadcrumbs > .miga-padre::before { content: "‹"; margin-right: 6px; font-size: 16px; line-height: 1; }
}

/* ══════════════════════════════════════════════════════════════════════════
   BARRA SUPERIOR EN TABLETA, 761–1100 px (DCC-06)
   ══════════════════════════════════════════════════════════════════════════
   Medido a 820px: la miga completa «Inicio / Equipos / Equipo UX» saltaba a una
   segunda línea (43px) dentro de una barra de 60px y dejaba a la entrega de
   banderas 179px, con el placeholder cortado («entrega una banc»). En este rango
   la miga se reduce al padre inmediato, como en móvil, y la entrega se queda con
   el espacio libre. */
@media (min-width: 761px) and (max-width: 1100px) {
  /* Sin encoger: con `flex-shrink` la miga cedía antes que la entrega y salía
     «‹ Equipc». Tope de ancho para nombres de sección largos. */
  .topbar .breadcrumbs { flex: 0 0 auto; max-width: 14rem; min-width: 0; overflow: hidden; flex-wrap: nowrap; white-space: nowrap; }
  .topbar .breadcrumbs > * { display: none; }
  .topbar .breadcrumbs > .miga-padre {
    display: inline-flex; align-items: center; min-height: 44px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--fg-dim);
  }
  .topbar .breadcrumbs > .miga-padre::before { content: "‹"; margin-right: 6px; font-size: 16px; line-height: 1; }
  /* R-01 — la entrega no puede salirse de su caja.
     Medido a 761–820 px: `.claim` medía 363..600 pero el campo seguía en 243 px
     (su ancho intrínseco: `width:auto` en un <input> es su `size`, no el hueco
     libre) y el botón quedaba en 607..651, fuera de la caja y DEBAJO de la lupa
     (elementFromPoint devolvía el SVG; el clic no llegaba). Causa: el
     <form class="navbar-form"> es un bloque que no participa del flex, así que
     el grupo nunca podía encoger por debajo del contenido. Formulario y grupo
     pasan a flex con min-width:0 y el campo parte de 0 y crece: cede ancho y el
     botón no se sale nunca. */
  /* El separador flexible se repartía el hueco con la entrega y, con el campo
     partiendo de 0, la dejaba en 24 px. En este rango el buscador está plegado
     tras la lupa: el hueco es de la entrega. */
  .topbar .top-spacer { flex: 0 0 0; }
  .topbar .claim { flex: 1 1 auto; min-width: 0; }
  .topbar .claim form,
  .topbar .claim .navbar-form { display: flex; width: 100%; min-width: 0; margin: 0; padding: 0; }
  /* material-dashboard.js envuelve el grupo en un <span class="bmd-form-group">
     (display:block, flex 0 1 auto) al cargar: medido, ese envoltorio se quedaba
     en 70 px y el campo en 24 aunque .claim tuviera 244. Entra en la cadena flex. */
  .topbar .claim .bmd-form-group { display: flex; flex: 1 1 auto; min-width: 0; padding: 0; margin: 0; }
  .topbar .claim .input-group { flex: 1 1 auto; flex-wrap: nowrap; width: 100%; min-width: 0; }
  .topbar .claim .form-control { flex: 1 1 auto; width: 0 !important; max-width: none; min-width: 0; }
  .topbar .claim .btn { flex: 0 0 auto; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ÁREA TÁCTIL DE LOS BOTONES EN MÓVIL (R-02, DIS-MPR-R01, DCC-05)
   ══════════════════════════════════════════════════════════════════════════
   Medido a 390 px: «Ir a Máquinas» (muro de actividad) 105x34 en /dashboard,
   /team/mine, /profile/me y /target/1, y «Captura tu primera bandera» 188x34 en
   /leaderboards. Cada corrección añadía una regla de 44 px para SU bloque
   (perfil.css, maquinas.css) y cada botón nuevo con .btn-sm volvía a nacer
   pequeño. La causa es que no había una regla común: aquí la hay, para todo
   .btn del frontend, solo donde se toca con el dedo. En escritorio no cambia.
   REV-CROMO-02: «donde se toca con el dedo» no es solo el ancho. A 820 px (un
   iPad) los .btn-sm y la entrega seguían en 34 px. `(pointer: coarse)` cubre
   tabletas y pantallas táctiles anchas sin tocar el escritorio con ratón. */
@media (max-width: 760px), (pointer: coarse) {
  /* Con la especificidad de `.btn.btn-sm{min-height:34px}` (academia-design.css),
     que es la que dejaba los botones en 34 px. min-height gana a cualquier
     `height` menor (p. ej. `.btn.btn-just-icon.btn-sm{height:30px}`). */
  .btn,
  .btn.btn-sm,
  .btn.btn-xs { min-height: 44px; }
  .btn:not(.btn-block) { display: inline-flex; align-items: center; justify-content: center; }
  .btn.btn-block { display: flex; align-items: center; justify-content: center; }
  /* El atributo hidden debe seguir ganando al display de arriba. */
  .btn[hidden] { display: none !important; }
}

/* Mismo criterio táctil para los botones de la barra y los iconos de equipo,
   que en ≤760 px ya tenían su regla (arriba y equipos.css) pero de 761 px en
   adelante medían 38 (.icon-btn), 34 (entrega) y 36 px (.equipo-icono-btn). */
@media (pointer: coarse) {
  .topbar .icon-btn { width: 44px; height: 44px; }
  .topbar .claim .form-control { height: 44px; min-height: 44px; }
  .topbar .claim .btn,
  .topbar .claim .btn-just-icon { width: 48px; height: 44px; min-height: 44px; }
  button.equipo-icono-btn,
  a.equipo-icono-btn { min-width: 44px; min-height: 44px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   BUSCADOR (EST-11, MAQ-05, EST-21)
   ══════════════════════════════════════════════════════════════════════════ */

/* Un solo borde (EST-21). academia-design.css restila todo input[type=search]
   con borde, fondo y alto mínimo de 44px, y esa regla ganaba a `.search input`:
   se veían tres contornos anidados (píldora, caja del input y la tecla «/»). */
.topbar .search input[type="search"],
.topbar .search input[type="search"]:focus {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  min-height: 0 !important;
  height: auto;
  padding: 0 !important;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.topbar .search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

/* DIS-MPR-R03: .search es un <div> y la etiqueta solo envuelve icono, campo y
   atajo. La etiqueta ocupa toda la píldora (el relleno pasa a ella) para que
   pulsar en cualquier punto de la caja siga enfocando el campo. */
.topbar .search { padding: 0; }
.topbar .search .search-campo {
  display: flex; align-items: center; gap: 9px;
  flex: 1 1 auto; align-self: stretch; min-width: 0;
  margin: 0; padding: 8px 12px;
  color: inherit; font: inherit; letter-spacing: normal; text-transform: none;
  cursor: text;
}

/* La lupa solo existe donde la caja no cabe. */
.cc-abrir-busqueda { display: none; }

@media (max-width: 1100px) {
  .cc-abrir-busqueda { display: grid; }
  .topbar { position: relative !important; }
  /* Plegada por omisión: antes simplemente se ocultaba, sin alternativa. */
  .topbar .search { display: none; }
  /* Desplegada: sobre la barra, a todo el ancho, con la lista debajo. */
  .topbar.buscando .search {
    display: flex;
    position: absolute;
    top: 8px; left: 12px; right: 64px;
    min-width: 0;
    height: 44px;
    z-index: 20;
    background: var(--bg-1);
  }
  .topbar.buscando .cc-abrir-busqueda {
    position: absolute;
    top: 8px; right: 12px;
    z-index: 21;
  }
  .topbar .search .kbd { display: none; }
}

/* Mensajes del buscador fuera del listbox (DIS-MPR-07): misma caja flotante
   que .search-results, pero es un role=status, no opciones. */
.search-estado {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  margin: 0; padding: 10px; z-index: 1200;
  background: var(--bg-1); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: 0 18px 40px -12px oklch(0 0 0 / 0.6);
  color: var(--fg-dim); font-size: 12px; text-align: center;
}

/* REV-CROMO-03: en móvil la entrega es la segunda fila de la barra y el estado
   y la lista del buscador flotan justo encima: «Escribe al menos 3 letras» se
   leía montado sobre el campo de bandera. Con el buscador desplegado la barra
   está en modo búsqueda (la caja ya tapa la primera fila): la entrega se oculta
   y vuelve al cerrarlo (Escape, lupa o toque fuera). `visibility` conserva el
   hueco, así que nada salta, y la saca del orden de tabulación. */
@media (max-width: 760px) {
  .topbar.buscando .claim { visibility: hidden; }
}

/* ══════════════════════════════════════════════════════════════════════════
   AVISOS FLOTANTES (bootstrap-notify) (DIS-MPR-02)
   ══════════════════════════════════════════════════════════════════════════
   material-dashboard.css pinta `.alert.alert-info{background:#00cae3;color:#fff}`
   (y lo mismo en verde, naranja y rojo): medido 1.99:1 en «Inicia sesión para
   ver esta red.», y la cruz de cierre de 11x13 px. academia-design.css ya
   tematiza `.alert-info`, pero con una clase menos y pierde. Aquí: fondo
   opaco del sistema (el aviso flota sobre la página, un fondo translúcido
   dejaría ver el contenido de detrás), texto --fg y el color de estado solo
   en el borde y el icono. */
.alert[data-notify].alert-info,
.alert[data-notify].alert-success,
.alert[data-notify].alert-warning,
.alert[data-notify].alert-danger {
  background: linear-gradient(var(--ac-info-suave), var(--ac-info-suave)), var(--bg-2);
  color: var(--ac-txt);
  border: 1px solid var(--line);
  border-left: 3px solid var(--ac-info);
  box-shadow: 0 18px 40px -12px oklch(0 0 0 / 0.6);
}
.alert[data-notify].alert-success {
  background: linear-gradient(var(--ac-exito-suave), var(--ac-exito-suave)), var(--bg-2);
  border-left-color: var(--ac-exito);
}
.alert[data-notify].alert-warning {
  background: linear-gradient(var(--ac-aviso-suave), var(--ac-aviso-suave)), var(--bg-2);
  border-left-color: var(--ac-aviso);
}
.alert[data-notify].alert-danger {
  background: linear-gradient(var(--ac-error-suave), var(--ac-error-suave)), var(--bg-2);
  border-left-color: var(--ac-error);
}
.alert[data-notify] a,
.alert[data-notify] .alert-link { color: var(--ac-acento); }
.alert[data-notify].alert-with-icon i[data-notify="icon"],
.alert[data-notify] i[data-notify="icon"] { color: var(--ac-info); }
.alert[data-notify].alert-success i[data-notify="icon"] { color: var(--ac-exito); }
.alert[data-notify].alert-warning i[data-notify="icon"] { color: var(--ac-aviso); }
.alert[data-notify].alert-danger i[data-notify="icon"] { color: var(--ac-error); }
.alert[data-notify] { padding-right: 52px; min-height: 46px; }
.alert[data-notify] button.close {
  /* bootstrap-notify pone en línea `top:50%; margin-top:-9px; right:10px`. */
  position: absolute; top: 1px !important; right: 4px !important; margin: 0 !important;
  min-width: 44px; min-height: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
  color: var(--ac-txt-2); opacity: 1; text-shadow: none;
}
.alert[data-notify] button.close .material-icons { color: inherit; font-size: 20px; }
.alert[data-notify] button.close:hover,
.alert[data-notify] button.close:focus-visible { color: var(--ac-txt); }

/* ══════════════════════════════════════════════════════════════════════════
   DESPLEGABLES DE PISTAS Y AVISOS
   ══════════════════════════════════════════════════════════════════════════ */
.dropdown-lista { min-width: 22rem; max-width: min(28rem, calc(100vw - 24px)); }
.dropdown-lista .dropdown-texto { cursor: default; white-space: normal; }
.dropdown-lista .aviso-nuevo { box-shadow: inset 2px 0 0 var(--accent); }
@media (max-width: 760px) {
  .dropdown-lista { min-width: 0; width: calc(100vw - 24px); }
}

/* ══════════════════════════════════════════════════════════════════════════
   PIE LEGAL DE LA BARRA LATERAL (EST-12)
   ══════════════════════════════════════════════════════════════════════════ */
.side-legal {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--line-soft);
  font-size: 11px;
}
.side-legal a {
  color: var(--fg-mute);
  text-decoration: none;
  min-height: 24px;
  display: inline-flex; align-items: center;
}
.side-legal a:hover,
.side-legal a:focus-visible { color: var(--accent); text-decoration: underline; }
.side-legal .sep { color: var(--fg-faint); }

/* Ficha de usuario activa en /profile/me (EST-14). */
.user-card.active { border-color: oklch(0.55 0.18 143 / 0.45); }
