/* Portado tal cual desde formulario.html.html (huemul-dev), líneas 12-151 --
   mismo look & feel, variables de tema para modo oscuro/táctil manuales
   (no prefers-color-scheme), sin framework. */

/* Un toque más chico en general (Roy: "quiero que todos los textos sean un
   poco más chicos") -- todo lo que usa rem se achica solo con esto. */
html { font-size: 16px; scroll-behavior: smooth; }
@media (max-width: 400px) { html { font-size: 15px; } }
/* Paleta HUEMUL v2 (rediseño Claude Design, ronda Problemas) -- mismos NOMBRES
   de variable que ya usaba toda la app, valores nuevos, así el resto de las
   pantallas (todavía con su layout viejo) hereda el color sin romperse.
   Naranja de urgencia (--urgente) y sage (--sage) son fijos en ambos temas
   a propósito -- el naranja es el único color con significado clínico. */
:root{
  --bg:#ECEAD3; --text:#1C231B; --accent:#3A4936; --accentFg:#ECEAD3; --input:#FFFDF7; --inputBd:rgba(28,35,27,.15); --muted:#8A9182;
  --panelBg:#FFFDF7; --panelBd: rgba(28,35,27,.15); --optBd: rgba(28,35,27,.08); --panelHdr: rgba(28,35,27,.07);
  --card:#ECEAD3; --cardBd: transparent; --header:#3A4936; --headerFg:#ECEAD3; --accent-rgb: 58,73,54;
  --chipTxt:#4B5245; --ph:#5F6659; --danger:#3B1314; --scrim:rgba(28,35,27,.42);
  --urgente:#E75428; --urgente-rgb:231,84,40; --sage:#A4A482; --sage-rgb:164,164,130;
  /* Escala de autonomía (Roy, AUTON_COLOR) -- fija en los dos temas, igual
     que urgente/sage. Obs.pasiva → Supervisión directa. auton-5/6/7:
     "Consulta dirigida" se separó en 3 niveles de atención con supervisión
     (Roy) -- 3 tonos nuevos entre auton-3 (ahora solo histórico) y auton-4. */
  --auton-1:#DDE0CB; --auton-2:#A4A482; --auton-3:#77835F; --auton-4:#3A4936;
  --auton-5:#687555; --auton-6:#59664B; --auton-7:#495840;
  --shadow-sm: 0 1px 2px rgba(28,35,27,.06), 0 1px 3px rgba(28,35,27,.08);
  --shadow-md: 0 2px 6px rgba(28,35,27,.08), 0 6px 18px rgba(28,35,27,.10);
  --shadow-lg: 0 8px 30px rgba(28,35,27,.16);
}
body.dark{
  --bg:#1C231B; --text:#ECEAD3; --accent:#A4A482; --accentFg:#1C231B; --input:#1A211A; --inputBd:rgba(236,234,211,.16); --muted:#7D8474;
  --panelBg:#252F23; --panelBd: rgba(236,234,211,.16); --optBd: rgba(236,234,211,.08); --panelHdr: rgba(236,234,211,.10);
  --card:#1C231B; --cardBd: transparent; --header:#111710; --headerFg:#A4A482; --accent-rgb: 164,164,130;
  --chipTxt:#BCC3B4; --ph:#A2A996; --danger:#C98A7E; --scrim:rgba(0,0,0,.6);
  --urgente:#E75428; --urgente-rgb:231,84,40; --sage:#A4A482; --sage-rgb:164,164,130;
  --auton-1:#DDE0CB; --auton-2:#A4A482; --auton-3:#77835F; --auton-4:#3A4936;
  --auton-5:#687555; --auton-6:#59664B; --auton-7:#495840;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.25);
  --shadow-md: 0 2px 6px rgba(0,0,0,.3), 0 6px 18px rgba(0,0,0,.35);
  --shadow-lg: 0 8px 30px rgba(0,0,0,.5);
}
/* Logo real (splash/login/header) -- dos <img> en el DOM, se muestra uno
   solo según el tema (mismo criterio que el resto: body.dark = tema oscuro).
   Evita cualquier parpadeo de "logo equivocado" que tendría un swap por JS. */
.logo-dark{ display:none; }
body.dark .logo-light{ display:none; }
body.dark .logo-dark{ display:inline-block; }
*{ -webkit-tap-highlight-color: transparent; }
body{ font-family: "Open Sans","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,sans-serif; background: var(--bg); color: var(--text); margin:0; padding:0 0 24px; min-height:100vh; display:flex; flex-direction:column; transition: background .3s, color .3s; -webkit-font-smoothing: antialiased; overscroll-behavior-y:contain; }
/* Con un sheet (Diagnóstico/Lugar/Residentes) abierto, el fondo no scrollea
   por su cuenta -- ver _sheetScrimSync() en app.js. */
body.sheet-open{ overflow:hidden; }
body.sheet-open #app{ overflow:hidden; }
#app, .login-card { max-width: 100%; margin-left:auto; margin-right:auto; width:100%; }
/* Arriba de 800px (viendo la app en una compu, típicamente durante desarrollo
   en localhost) se simula un celular real -- ancho Y alto acotados (antes
   solo el ancho quedaba limitado a 720px, ni celu ni tablet, y el alto
   estiraba sin límite con el scroll de toda la ventana; Roy: "definí los
   límites superior e inferior de la pantalla tipo celu" / "para no tener
   sorpresas al momento de ver la app"). 430×844 = proporción de un iPhone
   grande actual, centrado en la ventana con scroll PROPIO adentro.
   "transform" en #app (cualquier valor, acá uno sin efecto visual) hace que
   se vuelva el "containing block" de sus descendientes position:fixed --
   los sheets de abajo (Diagnóstico/Lugar/Residentes), su scrim y el splash
   quedan así anclados y recortados a los bordes de #app en vez de a toda la
   ventana del navegador, sin tener que duplicar cada uno a mano. */
@media (min-width: 800px){
  body{ background:#0000001a; justify-content:center; }
  body.dark{ background:#00000040; }
  #app, .login-card { max-width: 430px; box-shadow:0 0 0 1px var(--inputBd), var(--shadow-lg); }
  /* overflow:hidden acá (no auto) -- #app solo recorta las puntas
     redondeadas, el que scrollea de verdad es .screen.active más abajo.
     Un flex item con overflow:visible (.screen.active) que se pasa de la
     altura que le tocó no hace crecer el scroll de un ancestro más arriba
     de forma confiable entre navegadores -- Chrome headless (con el que
     probé esto) directamente no dejaba mover el scroll de #app ni a mano
     (scrollTop=N, scrollBy) aunque scrollHeight fuera mayor que clientHeight.
     El que tiene que scrollear tiene que ser el mismo elemento cuyo
     contenido se desborda. */
  #app{ background:var(--bg); height:min(844px,92vh); border-radius:24px; overflow:hidden; transform:translateZ(0); }
  .screen.active{ overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior-y:contain; }
  /* Mismos límites de "celu" que #app, para la pantalla de login (Roy) --
     antes el fondo crema se estiraba a todo el ancho de la ventana, sin
     silueta de teléfono. inset:0 (inline) + width/height explícitos +
     margin:auto la centran en una caja fija, igual que #app. transform la
     vuelve containing block de sus hijos position:fixed (el sheet de
     elegir sede/nombre), así quedan recortados a esta caja y no a toda la
     ventana. */
  #login-screen{ box-sizing:border-box; width:430px; height:min(844px,92vh); margin:auto; border-radius:24px; box-shadow:0 0 0 1px var(--inputBd), var(--shadow-lg); overflow-y:auto; transform:translateZ(0); }
}
/* flex:1 -- #app pasa a ocupar el resto del alto de body (que ya tiene
   min-height:100vh), en vez de encogerse a su contenido nada más. Esto es
   lo que le da a .screen.active (más abajo) un contenedor con altura de
   verdad para poder empujar .save-bar al fondo cuando el contenido es corto
   (Prácticas) -- ver el comentario de .save-bar en la sección más abajo.
   min-height:0 evita el bug clásico de flexbox donde un flex item no se
   achica más allá del alto natural de su contenido por default. */
#app { padding:0; flex:1; display:flex; flex-direction:column; min-height:0; }
/* flex:1 (arriba) trae flex-basis:0%, que en un contenedor columna PISA la
   "height" fija que le pusimos a #app para desktop (más arriba, dentro del
   @media) -- por eso el marco tipo celu había dejado de recortarse en
   828/844px y volvía a estirarse a toda la ventana (bug real: Roy lo notó
   al pedir "que la prueba de localhost tenga la altura de un celu"). Acá,
   más abajo en el archivo que la regla general de arriba (así gana en la
   cascada), flex:none le devuelve el control a la "height" fija en desktop
   -- en mobile (donde esta media query no aplica) sigue valiendo el
   flex:1 de siempre. */
@media (min-width: 800px){ #app{ flex:none; } }
/* Mismo flex:1/min-height:0 acá adentro, para que .screen.active ocupe el
   resto del alto de #app (después del header) y así .save-bar (más abajo,
   con margin-top:auto) tenga adónde empujarse. Sin esto, con poco contenido
   (Prácticas) el botón Guardar quedaba flotando a mitad de pantalla con un
   espacio muerto abajo en vez de pegado al fondo (Roy: "prefiero que quede
   arriba del botón el espacio muerto"). Con MUCHO contenido (Problemas) no
   cambia nada -- ya no hay margen para empujar, y .save-bar sigue "sticky"
   para no tener que scrollear hasta el fondo para llegar al botón. */
/* Menos aire arriba (Roy: "ese espacio que está en todas las pantallas") --
   solo el top, el resto del padding queda igual. */
.screen.active{ display:flex; flex-direction:column; flex:1; min-height:0; background:transparent; border:none; border-radius:0; padding:8px 12px 18px; box-shadow:none; }
h2{ text-align:center; color:var(--accent); font-size:clamp(1.5rem,5.5vw,1.8rem); margin: 2px 0 22px; font-weight:800; }
label{ margin-top:1.3em; display:block; font-weight:700; font-size:1.05rem; margin-bottom:2px; }
/* Único <a> de la app ("¿Olvidaste tu PIN?") -- sin esto quedaba azul por
   default del navegador, no del verde de la marca (mockup de Roy). a:link/
   a:visited del navegador son más específicos que un simple "a", por eso
   hace falta igualar esos selectores en vez de uno solo. */
a, a:link, a:visited{ color:var(--accent); }
/* Además del recorte general de arriba, los inputs bajan un poco más
   (Roy: "principalmente los de los input"). */
input, select, textarea{ width:100%; padding:15px 16px; margin-top:.4em; background: var(--input); border:2px solid var(--inputBd); border-radius:14px; font-size:.95rem; color: var(--text); box-sizing:border-box; transition: border-color .15s, box-shadow .15s; }
input:focus, select:focus, textarea:focus{ outline:none; border-color:var(--accent); box-shadow:0 0 0 4px rgba(var(--accent-rgb),.16); }
textarea{ font-family:inherit; resize:vertical; }
input::placeholder, textarea::placeholder{ color: var(--ph); }
small{ color:var(--muted); font-size:.88rem; display:block; margin-top:6px; }
button{ margin-top: 1.2em; padding:16px; width:100%; font-size:1.15rem; background: var(--accent); color:var(--accentFg); border:none; border-radius:16px; cursor:pointer; font-weight:800; box-shadow: var(--shadow-sm); transition: background .15s, box-shadow .15s, transform .08s; }
button:hover{ box-shadow: var(--shadow-md); }
button:active{ transform: translateY(1px); box-shadow: none; }
button.secondary{ background: transparent; color: var(--accent); border:2px solid var(--accent); margin-top:.6em; font-weight:700; box-shadow:none; }
button.secondary:hover{ background: rgba(var(--accent-rgb),.08); box-shadow:none; }
button.loading{ opacity:.75; pointer-events:none; }
button.success{ background:#2ecc71 !important; }
#toast-container{ position:fixed; bottom:80px; left:50%; transform:translateX(-50%); z-index:9999; display:flex; flex-direction:column-reverse; gap:8px; align-items:center; pointer-events:none; width:92%; max-width:420px; }
.toast{ pointer-events:auto; width:100%; padding:11px 16px; border-radius:12px; font-size:.88rem; font-weight:600; line-height:1.4; box-shadow:0 4px 18px rgba(0,0,0,.18); display:flex; align-items:center; gap:10px; animation:toastIn .22s ease; transition:opacity .3s ease,transform .3s ease; }
.toast.hide{ opacity:0; transform:translateY(10px); }
.toast-icon{ font-size:1.1rem; flex-shrink:0; }
.toast-msg{ flex:1; }
.toast-close{ background:transparent; border:none; color:inherit; cursor:pointer; font-size:1rem; opacity:.6; padding:0; margin:0; width:auto; margin-top:0; flex-shrink:0; line-height:1; }
.toast-close:hover{ opacity:1; }
.toast.success{ background:#1e8449; color:#fff; } .toast.error{ background:#c0392b; color:#fff; } .toast.warning{ background:#d68910; color:#fff; } .toast.info{ background:#1a5276; color:#fff; }
body.dark .toast.success{ background:#27ae60; } body.dark .toast.error{ background:#e74c3c; } body.dark .toast.warning{ background:#f39c12; } body.dark .toast.info{ background:#2980b9; }
@keyframes toastIn{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:translateY(0); } }
#splash{ position:fixed; inset:0; background:var(--bg); display:flex; align-items:center; justify-content:center; z-index:999; }
#splash img{ width:70vw; max-width:300px; }
#app.hidden{ display:none; }
.screen{ display:none; }
.screen.active{ display:flex; }
/* El buscador real de Diagnóstico/Lugar ahora vive ADENTRO de su sheet
   (z-index:50, ya por encima del scrim de por sí) -- el .picker de afuera
   (preview + ★) ya no necesita quedar levantado sobre el scrim como cuando
   el input vivía ahí mismo. Dejarlo con z-index propio (como antes) hacía
   que AMBOS pickers de afuera (Diagnóstico Y Lugar) quedaran brillando por
   encima del scrim apenas se abría cualquiera de los dos sheets -- daba la
   sensación de que "se resaltaba el otro buscador" al tocar uno solo (bug
   que reportó Roy). Sin z-index acá, el de afuera se atenúa junto con el
   resto del fondo cuando el scrim está activo, como cualquier otro contenido. */
.picker{ display:flex; gap:8px; align-items:center; }
.picker input{ flex:1; }
.panel{ margin-top:6px; border:1px solid var(--panelBd); border-radius:10px; background:var(--panelBg); overflow:hidden; box-shadow:var(--shadow-md); }
.panel-header{ display:flex; justify-content:space-between; align-items:center; padding:8px 10px; background:var(--panelHdr); }
.panel-title{ font-weight:800; }
/* Sin esto hereda width:100%+margin-top:1.2em del <button> base -- por eso
   se veía como un rectángulo ancho en vez de una X cuadrada (Roy). Ancho y
   alto fijos e iguales (55px, el alto que ya tenía con el padding heredado)
   en vez de aspect-ratio -- en un ítem flex sin tamaño explícito no forzaba
   el ancho de forma confiable. */
.panel-close{ border:none; background:transparent; cursor:pointer; font-size:16px; color:inherit; margin:0; width:55px; height:55px; padding:0; display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box; }
.results{ max-height:240px; overflow-y:auto; -webkit-overflow-scrolling:touch; }
.opt{ padding:10px; border-top:1px solid var(--optBd); cursor:pointer; line-height:1.25; }
.opt:hover{ background:rgba(0,0,0,.04); }
body.dark .opt:hover{ background:rgba(255,255,255,.06); }
.opt .match{ font-weight:800; }
/* Tarjeta de "no está en el catálogo, cargalo como X" (no contemplado en
   Diagnóstico, sugerir en Lugar) -- distinta del resto de las filas, con
   ícono + borde punteado naranja para que se note que es una salida
   alternativa, no un resultado más de la lista (Roy, siguiendo su mockup). */
.opt-usar-dx{ display:flex; align-items:center; gap:10px; margin:8px 10px; padding:10px 12px; border:1.5px dashed rgba(var(--urgente-rgb),.5); border-top:1.5px dashed rgba(var(--urgente-rgb),.5); border-radius:12px; background:rgba(var(--urgente-rgb),.08); font-size:.82rem; line-height:1.35; }
.opt-usar-dx:hover{ background:rgba(var(--urgente-rgb),.14); }
.opt-hint-icon{ flex:none; font-size:1.15rem; color:var(--urgente); }
.opt-hint-txt{ flex:1; color:var(--text); }
.panel-footer{ padding:6px 10px; background:rgba(0,0,0,.03); }
body.dark .panel-footer{ background:rgba(255,255,255,.06); }
input.error{ animation:shake .3s; box-shadow:0 0 0 2px #e57373; }
input.ok{ box-shadow:0 0 0 2px #81c784; }
@keyframes shake{ 0%{transform:translateX(0)} 25%{transform:translateX(-4px)} 50%{transform:translateX(4px)} 75%{transform:translateX(-4px)} 100%{transform:translateX(0)} }
.header-wrap{ background:var(--header); padding:12px 12px 0; border-radius:0 0 0 0; box-shadow:0 4px 16px rgba(0,0,0,.14); position:relative; z-index:5; }
.user-bar{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px; min-height:40px; }
.user-bar-brand{ display:flex; align-items:center; gap:8px; overflow:hidden; min-width:0; flex:1; }
.header-iso{ height:21px; width:auto; flex:none; opacity:.95; display:block; }
.user-badge{ font-size:1rem; font-weight:800; color:var(--headerFg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.user-controls{ display:flex; gap:4px; flex-shrink:0; }
/* Sin el cuadrado de fondo (Roy: "saquemos el cuadrado que contiene los
   emojis") -- quedan solo los íconos sueltos, el fondo aparece nada más al
   tocar/pasar el mouse, como feedback. */
/* display:flex + centrado (Roy: "el emoji de instalar app quedó
   desalineado") -- sin esto cada botón centra su emoji por line-height/
   baseline, que varía de glifo a glifo (📲 quedaba corrido de 🌙/🔑/🚪). */
.user-controls button{ width:36px; height:36px; margin:0; padding:0; font-size:1rem; background:transparent; color:var(--headerFg); border-radius:9px; box-shadow:none; transition:background .15s,transform .08s; display:flex; align-items:center; justify-content:center; line-height:1; }
.user-controls button:hover{ background:rgba(255,255,255,.28); box-shadow:none; }
.user-controls button:active{ transform:scale(.92); box-shadow:none; }
/* 📲 sigue más arriba que 🌙/🔑/🚪 con el centrado por flex solo (Roy) --
   el glifo de este emoji en particular trae su propio margen "de fábrica"
   más chico abajo que los otros, así que centrar la CAJA no centra el
   dibujo. Empujarlo un poco hacia abajo a mano. */
#btnInstalarApp{ position:relative; top:0; }
/* Roy: "que se pueda desplazar sin salirse del ancho de la pantalla" -- con
   7-8 pestañas (Gestión/Estadísticas se suman para docentes) el flex:1 de
   antes las apretaba a todas por igual hasta hacer que el texto se
   partiera en dos líneas. Ahora cada botón mide lo que necesita (flex:none
   + white-space:nowrap) y la fila entera scrollea horizontal si no entran
   todas -- el body nunca se desborda, el scroll queda contenido acá adentro. */
.bottom-nav{
  margin:0; background:transparent; border-radius:0; padding:0; display:flex; gap:2px; z-index:100;
  overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch;
}
/* Roy: "cómo puedo hacer para desplazar los menúes en la compu" -- con la
   scrollbar oculta (como estaba antes) no había ninguna pista visual ni
   forma de arrastrar con mouse en desktop, solo swipe táctil. Barra fina
   VISIBLE en vez de escondida -- clickeable/arrastrable con mouse, y
   discreta (2px) para no ensuciar el look en mobile. La rueda del mouse
   también la mueve sin Shift (ver _habilitarScrollHorizontalConRueda en
   app.js). Mismo tratamiento en #gestSubTabRow (Huecos AP + Bugs hacen que
   se desborde para Admin). */
.bottom-nav{ scrollbar-width:thin; scrollbar-color:rgba(236,234,211,.35) transparent; }
.bottom-nav::-webkit-scrollbar{ height:3px; }
.bottom-nav::-webkit-scrollbar-thumb{ background:rgba(236,234,211,.35); border-radius:999px; }
.bottom-nav::-webkit-scrollbar-track{ background:transparent; }
/* #gestSubTabRow tiene fondo claro (var(--input)) a diferencia del header
   oscuro de .bottom-nav -- mismo tratamiento, pulgar con var(--accent) en
   vez de crema translúcido para que se siga viendo en los dos temas. */
#gestSubTabRow.gest-subtabs-scroll{ scrollbar-width:thin; scrollbar-color:var(--accent) transparent; }
#gestSubTabRow.gest-subtabs-scroll::-webkit-scrollbar{ height:3px; }
#gestSubTabRow.gest-subtabs-scroll::-webkit-scrollbar-thumb{ background:var(--accent); border-radius:999px; opacity:.5; }
#gestSubTabRow.gest-subtabs-scroll::-webkit-scrollbar-track{ background:transparent; }
/* Ancho fijo chico (no todo el texto en una línea, Roy: "problemas
   prevalentes en dos líneas está bien, igual que prácticas... mis notas
   que sea una sola línea") -- vuelve al ancho angosto de siempre en vez de
   estirarse para que el texto largo entre en un renglón; los de un renglón
   corto (Mis notas, Historial) igual entran bien en ese ancho. */
.bottom-nav button{ flex:0 0 70px; width:70px; white-space:normal; margin:0; padding:9px 4px; border-radius:12px 12px 0 0; font-size:.78rem; font-weight:400; background:transparent; color:rgba(236,234,211,.72); border:none; box-shadow:none; cursor:pointer; transition:background .15s,opacity .15s,color .15s,box-shadow .15s; }
/* "Procedimientos" (14 letras, no rompe en dos) no entraba en los 70px de
   siempre y se desbordaba pisando la pestaña de al lado (Roy). */
#tab-practicas{ flex:0 0 92px; width:92px; }
/* "Estadísticas" (12 letras, no rompe en dos) excedía por poco los 70px
   de siempre (Roy). */
#tab-stats{ flex:0 0 80px; width:80px; }
.bottom-nav button:active{ transform:none; }
.bottom-nav button.active{ background:var(--bg); color:var(--accent); font-weight:400; box-shadow:0 -3px 10px rgba(0,0,0,.10); }
.bottom-nav button:not(.active):hover{ background:rgba(255,255,255,.12); color:var(--headerFg); box-shadow:none; }
.logo-footer{ margin-top:auto; padding:24px 0 20px; text-align:center; background:linear-gradient(to bottom, transparent, rgba(110,125,78,.06)); border-radius:20px 20px 0 0; }
.logo-footer img{ width:70vw; max-width:170px; opacity:.85; }
body.dark .logo-footer{ background:linear-gradient(to bottom, transparent, rgba(154,205,50,.05)); }
.qty-container{ height:54px; }
.qty-container input{ height:54px; }
.qty-row{ display:flex; gap:6px; align-items:stretch; flex-wrap:nowrap; height:54px; }
.hist-actions{ display:flex; align-items:center; gap:6px; margin-top:8px; }
.hist-actions button{ width:auto; margin-top:0; }
.btn-dup{ flex:1; font-weight:600; }
.acc-sum{ list-style:none; cursor:pointer; padding:10px 12px; border-radius:10px; background:rgba(0,0,0,.06); font-weight:800; color:var(--text); transition:background .15s,box-shadow .15s; }
.acc-sum:hover{ background:rgba(0,0,0,.09); }
body.dark .acc-sum{ background:rgba(255,255,255,.08); }
body.dark .acc-sum:hover{ background:rgba(255,255,255,.12); }
details[open] .acc-sum{ outline:2px solid rgba(255,255,255,.35); box-shadow:var(--shadow-sm); }
.acc-body{ margin-top:8px; padding:10px; border-radius:10px; background:rgba(255,255,255,.35); border:1px solid rgba(0,0,0,.08); box-shadow:var(--shadow-sm); }
body.dark .acc-body{ background:rgba(0,0,0,.18); border:1px solid rgba(255,255,255,.10); }
.fb-h4{ margin:12px 0 8px; color:var(--accent); }
.input-wrap{ position:relative; flex:1; }
/* margin-top:0 (Roy, Historial): .input-wrap es un ítem flex en la fila de
   buscador+Imprimir -- ahí los márgenes de sus hijos no colapsan con el
   padre (los ítems flex arman su propio contexto de formato), así que el
   margin-top:.4em de <input> (pensado para separarlo de un <label> arriba)
   se sumaba de más al alto real del wrap, dejando el botón de al lado más
   alto que el buscador al estirarse ambos con align-items:stretch. El
   espaciado de arriba del wrap se sigue controlando aparte (style inline). */
.input-wrap input{ padding-right:42px; margin-top:0; }
/* Lupa a la izquierda del buscador real (Diagnóstico/Lugar/Residentes,
   adentro de sus sheets) -- Roy: "que haya una lupa y diga 'buscar...'". */
.input-wrap.has-icon input{ padding-left:40px; }
.input-icon{ position:absolute; left:14px; top:50%; transform:translateY(-50%); opacity:.5; pointer-events:none; font-size:1rem; line-height:1; }
/* Residentes: sin X circular adentro del input -- la X vive afuera, en el
   cuadrado al lado (.clear-sq), así que no hace falta reservarle el hueco. */
.input-wrap.no-inline-clear input{ padding-right:16px; }
/* Cuadrado de limpiar del mismo alto que el input (mismo truco que .star-save
   -- align-self:stretch pisa el height:38px fijo de .icon-btn), fondo blanco
   con bordes redondeados (Roy: "cuadrados... blancos del mismo alto que los
   input"). */
/* El alto/ancho exactos (cuadrado real, igual altura que el input de al
   lado) los pone JS por medición directa (ver _syncSquareButtons en app.js)
   -- align-self:stretch + aspect-ratio dependía de que el navegador
   resolviera bien esa combinación en un flex row, y en la práctica no daba
   un cuadrado confiable (Roy lo confirmó dos rondas seguidas). Acá solo
   queda la pinta (fondo, radio, ícono); flex:none para que no se estire ni
   se achique solo por el flex del .picker. */
.clear-sq{ font-size:1.1rem; flex:none; background:#fff; border-radius:10px; touch-action:manipulation; }
body.dark .clear-sq{ background:#fff; color:#1C231B; }
/* Botón de estado cerrado para Diagnóstico/Lugar: se ve como un input (para
   mantener la jerarquía visual de "acá va el diagnóstico/lugar"), pero es un
   <button> que abre el sheet donde vive el buscador de verdad -- ya no hay
   dos cajas que parecen ambas de escribir (Roy: "el lugar que parece para
   escribir solo nos lleva al verdadero lugar para escribir"). */
/* .picker-preview-wrap (flex:1, position:relative) es lo que ahora comparte
   la fila con la ★ (Roy: "pongamos la estrella en la pantalla de inicio");
   adentro, .picker-preview ocupa el 100% y le deja hueco a la derecha para
   la X que aparece una vez elegido algo (mismo truco que .input-wrap/
   .clear-btn de los inputs reales). */
.picker-preview-wrap{ position:relative; flex:1; min-width:0; }
.picker-preview-wrap .picker-preview{ padding-right:42px; }
.picker-preview{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; background:var(--input); border:2px solid var(--inputBd); border-radius:14px; padding:15px 16px; margin:0; font-size:.95rem; font-weight:400; color:var(--text); box-shadow:none; transition:border-color .15s; }
.picker-preview:hover{ box-shadow:none; border-color:var(--accent); }
.picker-preview:active{ transform:none; }
.picker-preview-icon{ flex:none; opacity:.5; font-size:1rem; }
.picker-preview-txt{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.picker-preview-txt.is-placeholder{ color:var(--ph); }
/* touch-action:manipulation -- sin esto, algunos navegadores mobile esperan
   ~300ms antes de disparar el click (para distinguirlo de un doble-tap de
   zoom), lo que se sentía como que "a veces demora" en borrar (Roy). */
/* z-index:1 -- no cambia nada visual (mismo lugar, mismo tamaño), pero
   garantiza que quede SIEMPRE por encima del botón de abajo (.picker-preview,
   que ocupa toda la fila) para el hit-test del toque, en vez de confiar en
   que el orden del HTML alcance. Probado con clicks simulados (precisos,
   siempre en el centro) y no falla nunca -- así que el candidato que queda
   es el tamaño del blanco al dedo: 28px es chico para un toque real (debajo
   del mínimo de 44px que recomiendan Apple/Google), un dedo real cae fácil
   un poco afuera. El ::after de acá abajo agranda el ÁREA TOCABLE a ~44px
   sin agregarle nada visible (sin fondo/borde propio) -- no cambia en nada
   cómo se ve el botón (Roy: "no modifiquemos nada estético"), solo lo hace
   más fácil de acertar. */
.clear-btn{ position:absolute; right:8px; top:50%; transform:translateY(-50%); width:28px; height:28px; margin:0; padding:0; border:none; border-radius:999px; cursor:pointer; display:none; background:rgba(0,0,0,.10); color:inherit; line-height:1; touch-action:manipulation; z-index:1; }
.clear-btn::after{ content:""; position:absolute; inset:-8px; }
body.dark .clear-btn{ background:rgba(255,255,255,.10); }
.clear-btn.show{ display:inline-flex; align-items:center; justify-content:center; }
.qty-row .qty-btn:last-child{ margin-left:2px; }
.qty-btn.pos{ background:#5a8a3a; } .qty-btn.pos:hover{ background:#4a7a2a; }
.qty-btn.neg{ background:#c0392b; } .qty-btn.neg:hover{ background:#a93226; }
body.dark .qty-btn.pos{ background:#6aaa44; } body.dark .qty-btn.neg{ background:#e74c3c; }
.hist-actions{ display:flex; gap:8px; align-items:center; margin-top:8px; }
.hist-actions .btn-dup{ flex:1; padding:.55em .7em !important; margin:0 !important; }
.hist-actions .btn-delta{ padding:.35em .55em !important; margin:0 !important; width:auto !important; white-space:nowrap; }
.input-clear{ position:relative; }
.input-clear input{ padding-right:40px; }
.clear-x{ position:absolute; right:8px; top:50%; transform:translateY(-50%); border:none; background:transparent; color:inherit; cursor:pointer; font-size:18px; line-height:1; opacity:.7; display:none; }
.clear-x:hover{ opacity:1; }
#participacion-wrap{ margin-top:10px; display:none; }
#participacion-wrap label{ margin-top:0; margin-bottom:6px; }
/* Sin recuadro (Roy: "se ve en círculos blancos uno al lado del otro, sin
   rectángulo que los agrupe") -- el nombre + "Sacar" arriba, los círculos
   sueltos debajo, la separación entre residentes es solo espacio. */
.pax-card{ border-radius:12px; padding:2px 0; margin-bottom:14px; }
.pax-card-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:6px; }
.pax-card-name{ font-weight:800; font-size:.85rem; color:var(--accent); }
.pax-sacar{ flex:none; font-size:.72rem; font-weight:700; color:var(--danger); cursor:pointer; padding:4px 9px; border-radius:999px; background:rgba(59,19,20,.08); }
body.dark .pax-sacar{ background:rgba(201,138,126,.14); }
.pax-chips{ display:flex; gap:8px; flex-wrap:wrap; }
.pax-chip{ padding:8px 14px; border-radius:999px; font-size:.9rem; font-weight:700; border:2px solid var(--inputBd); background:transparent; color:var(--chipTxt); cursor:pointer; transition:background .13s,color .13s,border-color .13s,box-shadow .13s; margin:0; width:auto; margin-top:0; box-shadow:none; }
.pax-chip.sel{ background:var(--accent); color:var(--accentFg); border-color:var(--accent); box-shadow:0 2px 8px rgba(var(--accent-rgb),.35); }
/* Chip anulado (p.ej. rol de docente cuando la sede ya quedó fija por otro
   rol -- Red Docente/Coordinador General, ver _gestDocCeroSyncLock). */
.pax-chip:disabled{ opacity:.35; cursor:not-allowed; }
/* Cohorte de Estadísticas (docente): fondo blanco (no transparente como el
   .pax-chip base) y un toque más angostos -- acotado a este grupo puntual,
   el resto de los .pax-chip de la app (tipo de resolución, etc.) sigue igual. */
#stats2AnioChips .pax-chip{ background:#fff; padding:8px 11px; }
body.dark #stats2AnioChips .pax-chip{ background:rgba(255,255,255,.08); }
#stats2AnioChips .pax-chip.sel{ background:var(--accent); }
/* Chips de "Período" en los sheets de filtro (Estadísticas y Resumen,
   mismo contenedor que arma _stats2RenderPeriodoChips en los dos) -- el
   seleccionado sigue siendo la píldora rellena de siempre, pero el resto
   pasa a texto plano sin borde ni fondo (Roy, mockup). Acotado a estos dos
   contenedores puntuales, no toca el resto de los .pax-chip de la app. */
#stats2PeriodoChips .pax-chip:not(.sel), #fbPeriodoChips .pax-chip:not(.sel){ border:none; background:transparent; padding:8px 6px; }
#stats2PeriodoChips .pax-chip.sel, #fbPeriodoChips .pax-chip.sel{ padding:8px 20px; }
/* "Distribuidos en todo el ancho" (Roy): 3 columnas parejas por fila (Todo/
   30/90 arriba, los 3 años abajo) en vez del flex-wrap apiñado a la
   izquierda que dejaba hueco vacío a la derecha. */
#stats2PeriodoChips, #fbPeriodoChips{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px 4px; }
#stats2PeriodoChips .pax-chip, #fbPeriodoChips .pax-chip{ text-align:center; }
.emoji-chip{ font-size:1.6rem; line-height:1; padding:13px 0; border-color:var(--inputBd); flex:1; text-align:center; border-radius:14px; }
.emoji-chip.sel{ background:var(--accent); border-color:var(--accent); }
.emoji-row{ display:flex; gap:8px; margin:.5em 0 .3em; }
.ref-toggle{ background:transparent; border:none; color:var(--accent); font-size:.85rem; font-weight:600; text-decoration:underline; cursor:pointer; padding:2px 0; margin:6px 0 0; width:auto; }
.ref-table{ margin:8px 0 4px; padding:12px 14px; background:var(--panelHdr); border-radius:12px; font-size:.88rem; }
.ref-table div{ padding:4px 0; display:flex; gap:10px; align-items:center; }
.ref-table .ref-emoji{ font-size:1.3rem; width:30px; text-align:center; flex-shrink:0; }
.qty-btn{ padding:0 .3em !important; width:auto !important; margin:0 !important; border-radius:12px !important; font-size:1.05rem !important; font-weight:700 !important; line-height:1 !important; border:none !important; color:#fff !important; cursor:pointer; flex:1; min-width:0; align-self:stretch; box-shadow:none !important; transition:background .13s,transform .08s; }
.qty-btn:active{ transform:scale(.94); }
.pax-simple{ display:flex; gap:6px; flex-wrap:wrap; margin-top:6px; }
/* Solo/Asistido (Prácticas) -- dos píldoras grandes lado a lado, mismo
   mockup que mandó Roy. Mismo alto que la píldora de cantidad (54px).
   Mismo trato visual que "Tipo de resolución" en Problemas (.urg-chip):
   blanco/rectangular (no transparente/pill) sin elegir, se llena de verde
   al elegir (Roy: "todos los botones quiero que sean de ese estilo"). */
.pax-toggle-row{ display:flex; gap:8px; margin-top:6px; }
.pax-toggle{ flex:1; height:54px; display:flex; align-items:center; justify-content:center; gap:8px; border-radius:11px; border:1.5px solid var(--inputBd); background:var(--input); color:var(--chipTxt); font-weight:700; font-size:.9rem; margin:0; width:auto; box-shadow:none; transition:background .13s,color .13s,border-color .13s; }
.pax-toggle-emoji{ font-size:1.2rem; line-height:1; }
.pax-toggle.sel{ background:var(--accent); color:var(--accentFg); border-color:var(--accent); }
.pax-card.error-pax{ box-shadow:0 0 0 2px #e57373; }
.emoji-row.error-row{ box-shadow:0 0 0 2px #e57373; border-radius:12px; }
.icon-btn{ flex:0 0 auto; width:38px; height:38px; border:1.5px solid var(--inputBd); border-radius:8px; background:var(--panelHdr); color:var(--text); cursor:pointer; font-size:1.1rem; display:inline-flex; align-items:center; justify-content:center; padding:0; margin:0; line-height:1; box-shadow:none; transition:background .15s,transform .08s; }
body.dark .icon-btn{ background:rgba(255,255,255,.08); }
.icon-btn:hover{ background:rgba(0,0,0,.13); box-shadow:none; }
.icon-btn:active{ transform:scale(.92); box-shadow:none; }
body.dark .icon-btn:hover{ background:rgba(255,255,255,.14); }
.icon-btn.danger{ color:var(--danger); border-color:rgba(59,19,20,.25); }
body.dark .icon-btn.danger{ border-color:rgba(201,138,126,.35); }
/* Editar/Borrar de Notas, en la cabecera de la tarjeta junto al título
   (Roy: "en la misma línea... más compactos, como en la pantalla
   problemas") -- mismo look que .icon-btn pero más chico, para que entre
   junto con título/fecha/estrella en una sola línea. */
.icon-btn-sm{ width:28px; height:28px; font-size:.9rem; border-radius:7px; }
/* Mockup de Roy: campos de sede/nombre/año color crema (--bg, el mismo tono
   de fondo de toda la app -- se ven "hundidos" contra la tarjeta blanca del
   login), sin borde marcado. Misma clase la usa el input de PIN y su botón
   del ojito (.login-field), para que los tres campos del login se vean
   parejos. */
.login-pick{ width:100%; text-align:left; background:var(--bg); color:var(--text); border:1.5px solid var(--inputBd); border-radius:14px; padding:15px 16px; margin:.4em 0 .6em; font-size:1.05rem; font-weight:400; cursor:pointer; box-shadow:none; transition:border-color .15s,box-shadow .15s; }
.login-pick:hover{ border-color:var(--accent); box-shadow:none; }
/* Alto fijo (54px) en vez de dejar que el padding+línea de texto lo decida
   solo -- .login-eye-btn necesita ese mismo número para el cuadrado de al
   lado, y dejarlo fijo en los dos evita el lío de calcularlo en tiempo real
   (probamos aspect-ratio y un ResizeObserver, ninguno daba un resultado
   estable: el ResizeObserver hasta entraba en loop, cada vez el uno hacía
   crecer al otro por el align-items:stretch de la fila). */
.login-field{ background:var(--bg); border:1.5px solid var(--inputBd); box-shadow:none; height:54px; box-sizing:border-box; }
.login-field:focus{ box-shadow:none; border-color:var(--accent); }
/* Cuadrado de verdad, mismo alto fijo que .login-field (Roy). Fondo blanco
   (--input), no crema como el resto de los campos del login. */
/* font-size más grande (Roy: "el emoji se ve borroso") -- los emoji a color
   se ven pixelados/borrosos cuando el navegador los agranda desde un
   tamaño de fuente chico; a un tamaño más cercano al bitmap nativo del
   emoji se ven nítidos. */
/* Emoji más chico (Roy), el cuadrado de 54x54 de afuera queda igual -- solo
   el glifo adentro se achica. A un tamaño menor también se ven los trazos
   del ojo más finos (el emoji a color se vuelve más "delicado" cuanto
   menos lo agranda el navegador desde su bitmap nativo). */
button.login-eye-btn{ background:var(--input); border:1.5px solid var(--inputBd); color:var(--text); box-shadow:none; margin:.4em 0 .6em; padding:0; box-sizing:border-box; flex:none; width:54px; height:54px; font-size:1.15rem; line-height:1; display:flex; align-items:center; justify-content:center; }
button.login-eye-btn:hover{ box-shadow:none; }
/* Menos aire entre sede/nombre/PIN (Roy) -- antes 1.3em antes de cada label
   + 1em después de cada campo, se sentía muy separado. Escapado a la
   pantalla de login para no afectar el resto de los formularios (Problemas,
   Gestión, etc. siguen con el espaciado de siempre). */
#login-screen label{ margin-top:.7em; }
@keyframes spin { to { transform: rotate(360deg); } }
/* box-sizing:border-box -- el padding+border inline (24px 20px + 1px) hacía
   que el ancho real superara su propio max-width:360px, desbordando el
   nuevo marco de "celu" de #login-screen y corriendo todo lo de adentro
   (el logo, sobre todo) del centro. */
.login-card{ box-shadow: var(--shadow-lg); box-sizing:border-box; }

/* Placeholder de pantallas todavía no portadas (slice 1: solo Problemas) */
.screen-placeholder{ text-align:center; opacity:.7; padding:40px 16px; }

/* Favoritos (Problemas/Prácticas/Lugares/Residentes) y listas de Gestión --
   gris cuando no es favorito, el naranja de "activo" cuando sí lo es (Roy:
   "así se distingue bien lo fav de lo no fav" -- antes ambos estados eran el
   mismo naranja, distinguidos solo por opacidad, poco claro). Esto SÍ es
   parejo en toda la app (Prácticas incluida) -- es solo color/estado. */
.star-save{ font-size:1.2rem; color:var(--muted); opacity:1; }
.star-save.in-favs{ color:var(--urgente); }
.star-view{ color:var(--urgente); font-size:1.2rem; }
/* El cuadrado blanco es para Problemas Y Prácticas -- las dos pantallas ya
   rediseñadas con el mismo patrón de sheet (Roy pidió mirror explícito de
   Problemas para Prácticas). Sigue acotado por pantalla (no una regla
   suelta para toda la app) porque otras pantallas sin rediseñar todavía
   (Feedback, Gestión) también usan la clase .star-save/.icon-btn genérica
   y esta pinta no les corresponde -- mismo criterio que evitó la fuga a
   Prácticas la ronda pasada ("el cambio que hiciste... lo hiciste en el
   lugar incorrecto"). El alto/ancho exactos los pone JS por medición
   directa (_syncSquareButtons en app.js, mismo comentario que en .clear-sq
   de más arriba). */
#screen-problemas .star-save, #screen-practicas .star-save{ flex:none; background:#fff; border-radius:10px; }
body.dark #screen-problemas .star-save, body.dark #screen-practicas .star-save{ background:#fff; }

/* Fila de resultado con estrella de favorito inline (Diagnóstico/Lugar) --
   favoritos ordenados primero por la propia función de render, esto es
   solo la pinta de la fila. Tocar la estrella no dispara el pick de la fila
   (event.stopPropagation() en el onclick). */
.fav-opt{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
/* Además de la ★ resaltada, toda la fila se destaca con un naranja pálido
   (Roy: "que los fav... tengan un naranja pálido que los destaque"). */
.fav-opt.is-fav-row{ background:rgba(var(--urgente-rgb),.10); }
.opt-txt{ flex:1; min-width:0; }
.opt-star{ flex:none; font-size:1.05rem; line-height:1; color:var(--muted); cursor:pointer; padding:2px 4px; margin:-2px -4px; }
.opt-star:hover{ opacity:.8; }
.opt-star.is-fav{ opacity:1; color:var(--urgente); }
.opt-star.is-fav:hover{ opacity:1; }

/* Residentes: pestañas Mi sede/Otras sedes, grupos guardados como chips
   dentro del mismo sheet, y cada fila con estrella (favorito) + "+"/"✓"
   (agregar a esta carga) -- las dos acciones son independientes. */
.res-sede-tabs{ display:flex; gap:6px; padding:9px 13px 0; }
.res-sede-tab{ flex:1; height:38px; margin:0; padding:0; border-radius:10px; border:1.5px solid var(--inputBd); background:transparent; color:var(--chipTxt); font-weight:700; font-size:.85rem; box-shadow:none; }
.res-sede-tab.sel{ background:var(--accent); border-color:var(--accent); color:var(--accentFg); }
.res-grupos-wrap{ padding:9px 13px; border-bottom:1px solid var(--optBd); background:rgba(var(--accent-rgb),.04); }
.res-grupos-head{ display:flex; align-items:center; gap:8px; margin-bottom:7px; }
.res-grupos-head .legend-box-title{ flex:1; }
/* Misma forma de píldora que los chips de grupo (Roy: "que esté dentro de
   una forma como la de los grupos") -- antes era un link subrayado suelto,
   ahora combina con los .res-grupo-chip de al lado. */
.res-grupos-head .ref-toggle{ margin:0; font-size:.78rem; font-weight:700; text-decoration:none; border-radius:999px; padding:8px 12px; background:rgba(var(--accent-rgb),.16); }
.res-grupos-chips{ display:flex; gap:6px; flex-wrap:wrap; }
.res-grupo-chip{ display:flex; align-items:center; border-radius:999px; overflow:hidden; background:rgba(var(--accent-rgb),.16); }
.res-grupo-label{ padding:8px 12px; font-size:.78rem; font-weight:700; color:var(--accent); cursor:pointer; }
.res-grupo-add{ display:inline-flex; align-items:center; padding:8px 12px; border-radius:999px; border:1.5px dashed rgba(var(--accent-rgb),.45); color:var(--accent); font-size:.78rem; font-weight:700; cursor:pointer; }
.opt-sumado{ flex:none; white-space:nowrap; font-size:.66rem; font-weight:800; letter-spacing:.04em; color:var(--accent); opacity:.75; }
.res-grupo-icon{ width:30px; height:34px; display:inline-flex; align-items:center; justify-content:center; font-size:.75rem; cursor:pointer; background:rgba(0,0,0,.06); }
.res-grupo-icon.danger{ color:var(--danger); }
.opt-add{ flex:none; font-size:.95rem; line-height:1; opacity:.55; padding:2px 4px; font-weight:800; color:var(--accent); }
.opt-add.is-added{ opacity:1; }
.res-opt{ gap:10px; }
.fav-item{ display:flex; align-items:center; gap:6px; padding:9px 10px; border-top:1px solid var(--optBd); transition:background .15s; }
.fav-item:hover{ background:rgba(0,0,0,.03); }
body.dark .fav-item:hover{ background:rgba(255,255,255,.04); }
.fav-item-label{ flex:1; font-size:.88rem; cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; line-height:1.3; }
.fav-item-label:hover{ font-weight:800; }
.fav-icon-btn{ border:none; background:transparent; cursor:pointer; font-size:.95rem; padding:4px; opacity:.7; color:var(--text); width:auto; margin:0; }
.fav-icon-btn:hover{ opacity:1; }
.fav-section-title{ padding:6px 10px 2px; font-size:.72rem; font-weight:800; text-transform:uppercase; letter-spacing:.05em; opacity:.5; }

/* Vista imprimible del historial propio (ver abrirVistaImprimible() en app.js) --
   oculta en pantalla, es lo único visible al imprimir/exportar a PDF. */
#print-view{ display:none; }
#print-view h1{ font-size:1.3rem; margin:0 0 4px; }
#print-view .pv-meta{ font-size:.85rem; color:#555; margin-bottom:18px; }
#print-view h2{ font-size:1.05rem; text-align:left; color:#000; margin:20px 0 8px; border-bottom:2px solid #000; padding-bottom:4px; }
#print-view table{ width:100%; border-collapse:collapse; font-size:.82rem; }
#print-view th, #print-view td{ border:1px solid #999; padding:5px 7px; text-align:left; vertical-align:top; }
#print-view th{ background:#eee; }
#print-view .pv-nota{ font-style:italic; color:#333; }
@media print{
  body > *:not(#print-view){ display:none !important; }
  #print-view{ display:block !important; color:#000; background:#fff; }
}

/* ===== Rediseño Problemas (ronda 1, Claude Design) ===== */

/* Sheet modal: los paneles de Diagnóstico/Lugar/Residentes (y sus favoritos)
   pasan de "panel debajo del input" a hoja que sube desde abajo, con scrim
   detrás -- misma lógica JS de apertura/cierre de siempre, solo se les suma
   la clase .sheet y un scrim compartido (#sheetScrim). */
.sheet-scrim{ position:fixed; inset:0; background:var(--scrim); z-index:40; }
.panel.sheet{ position:fixed; left:0; right:0; bottom:0; top:auto; z-index:50; margin:0; border-radius:20px 20px 0 0; max-height:76vh; display:flex; flex-direction:column; box-shadow:var(--shadow-lg); animation:sheetUp .18s ease; }
@keyframes sheetUp{ from{ transform:translateY(16px); opacity:.5; } to{ transform:translateY(0); opacity:1; } }
/* min-height:0 es el punto real -- sin esto, un hijo flex:1 con más
   contenido que el alto disponible NO se achica (default min-height:auto
   respeta el alto natural del contenido), así que crecía más allá del
   .panel.sheet (que sí está bien topeado a max-height:76vh) y como ese
   padre tiene overflow:hidden, todo lo que sobraba quedaba cortado en vez
   de scrolleable (Roy: con 14 sedes "solo me deja seleccionar lo que se ve
   o escribir lo que no se ve"). */
.panel.sheet .results{ flex:1; min-height:0; max-height:none; }
.panel.sheet .panel-footer{ flex:none; }
/* Sin el panel-header (barra "Resultados"/✕ que Roy sacó de los 3 sheets --
   se veía como un cuarto cuadro vacío para escribir), la lista de resultados
   arranca pegada a la esquina redondeada de arriba; un poco de aire para que
   no quede tan pegado. */
.panel.sheet > .results:first-child{ padding-top:8px; }
/* Espacio chico entre el input real (adentro del sheet) y lo que sigue
   debajo -- ni la lista de resultados ni las pestañas de sede (Residentes)
   quedaban pegadas al input (Roy: "no muy grande"). */
.panel.sheet > .picker + .results,
.panel.sheet > .picker + .res-sede-tabs{ margin-top:10px; }

/* Cantidad: píldora −/N/+ con +2/+5 al lado (reemplaza la fila de botones sueltos) */
.qty-pill-row{ display:flex; gap:6px; align-items:stretch; }
.qty-pill{ flex:1; display:flex; align-items:center; border-radius:12px; border:2px solid var(--inputBd); background:var(--input); overflow:hidden; height:54px; }
/* Ayuda visual (Roy): + en verde (var(--accent) ya es un verde), − en
   naranja -- para que la función quede clara de un vistazo. Compartido por
   Problemas, Prácticas y el formulario de Editar en Historial (misma
   clase en los tres). */
.qty-pill-btn{ width:50px; height:54px; flex:none; margin:0; padding:0; border-radius:0; background:transparent; box-shadow:none; font-size:1.4rem; font-weight:700; line-height:1; color:var(--accent); }
.qty-pill-btn.qty-pill-minus{ color:var(--urgente); }
.qty-pill-btn:hover{ background:rgba(var(--accent-rgb),.08); box-shadow:none; }
.qty-pill-btn:active{ transform:scale(.94); }
.qty-pill-input{ flex:1; min-width:0; text-align:center; font-weight:400; font-size:1.2rem; border:none !important; background:transparent !important; margin:0 !important; padding:0 !important; box-shadow:none !important; -moz-appearance:textfield; }
.qty-pill-input:focus{ box-shadow:none !important; }
/* Sacar las flechitas nativas del <input type=number> -- ya tenemos los
   botones −/+ propios (.qty-pill-btn), las flechitas del navegador sobraban. */
.qty-pill-input::-webkit-inner-spin-button, .qty-pill-input::-webkit-outer-spin-button{ -webkit-appearance:none; margin:0; }
.qty-quick{ flex:none; width:54px; margin:0; padding:0; border-radius:12px; background:rgba(var(--accent-rgb),.1); color:var(--accent); font-weight:700; font-size:.85rem; box-shadow:none; }
.qty-quick:hover{ background:rgba(var(--accent-rgb),.18); box-shadow:none; }
.qty-quick:active{ transform:scale(.94); }

/* Sospecha: interruptor aparte en vez de un 4° chip de urgencia */
.sosp-row{ display:flex; align-items:center; gap:9px; margin-top:10px; cursor:pointer; }
.sosp-track{ width:40px; height:24px; flex:none; border-radius:999px; background:var(--inputBd); position:relative; transition:background .18s; display:inline-block; }
.sosp-track .sosp-knob{ position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:999px; background:#fff; box-shadow:0 1px 3px rgba(28,35,27,.3); transition:transform .18s; }
.sosp-track.sel{ background:var(--urgente); }
.sosp-track.sel .sosp-knob{ transform:translateX(16px); }
.sosp-label{ font-weight:600; font-size:.95rem; }

/* Título de sección en mayúsculas ("Qué atendiste" / "Cuántos y dónde" /
   "Cómo participaste"), con o sin botón de leyenda al lado */
.sect-label{ display:flex; align-items:center; gap:6px; margin:1.3em 0 .3em; }
.sect-label-txt{ font-size:.68rem; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }

/* Leyenda de referencia (grupo etario / urgencia / participación) */
.legend-btn{ width:18px; height:18px; flex:none; margin:0; padding:0; border-radius:999px; background:var(--panelHdr); color:var(--muted); font-size:.7rem; font-weight:700; box-shadow:none; line-height:1; }
.legend-btn:hover{ box-shadow:none; background:var(--panelHdr); opacity:.8; }
/* Un toque más chico y con más interlineado (Roy, siguiendo la escala
   tipográfica de la identidad: esto es una "aclaración", no "cuerpo de
   texto"). */
.legend-box{ display:flex; flex-direction:column; gap:7px; background:var(--input); border:1.5px solid var(--inputBd); border-radius:11px; padding:9px 11px; margin:6px 0 10px; font-size:.76rem; line-height:1.5; color:var(--text); }
.legend-box-title{ font-weight:800; font-size:.68rem; text-transform:uppercase; letter-spacing:.06em; opacity:.65; }
.legend-sep{ height:1px; background:var(--optBd); margin:2px 0; }
.legend-row{ display:flex; flex-wrap:wrap; gap:9px; }
.legend-row > div{ display:flex; align-items:center; gap:6px; white-space:nowrap; }

/* Checklist de "Etiquetas" (Roy) -- mismo cuadro blanco que .legend-box,
   pero de tamaño normal (no ".76rem" de aclaración): esto se toca, no
   solo se lee. */
.etiqueta-row{ display:flex; align-items:center; gap:9px; font-size:.88rem; font-weight:600; cursor:pointer; }
.etiqueta-row input[type="checkbox"]{ flex:none; width:19px; height:19px; accent-color:var(--accent); cursor:pointer; margin:0; }

/* "+ Otro residente" / "+ Nota": dos toggles cortos lado a lado, cada uno
   se estira al abrirse (el otro sigue angosto, solo su summary). */
.link-row{ display:flex; gap:14px; flex-wrap:wrap; align-items:flex-start; margin-top:6px; }
.link-row > details{ flex:1 1 auto; min-width:130px; }
/* Abierto, cada <details> pasa a ocupar toda la fila (en vez de compartirla
   50/50 con el otro) -- si no, el textarea de "+ Nota" quedaba angosto,
   comprimido en su mitad de la fila (Roy: "que ocupe todo el ancho"). Como
   .link-row ya tiene flex-wrap, el otro <details> (cerrado) baja a su propia
   línea solo. */
.link-row > details[open]{ flex:1 1 100%; }

/* Chips de ancho animado (etario / participación): círculo con solo emoji sin
   elegir, se estiran y muestran la etiqueta al seleccionarse. */
.pax-chip.anim, .emoji-chip.anim{ display:flex; align-items:center; justify-content:center; gap:6px; overflow:hidden; white-space:nowrap; transition:flex .15s,padding .15s,background .13s,color .13s,border-color .13s; }
.pax-chip.anim{ flex:0 0 44px; height:44px; padding:0; background:var(--input); }
/* Roy: "al seleccionar un tipo, todos los otros bajen, no importa si están
   a la izquierda o derecha" -- el seleccionado se fuerza a ocupar toda la
   fila (flex-basis 100%, dentro de .pax-chips que ya tiene flex-wrap) y se
   reordena visualmente primero (order:-1) sin importar su posición real en
   el HTML. Así el resto (todos sin seleccionar, mismo orden entre ellos)
   siempre cae junto a una segunda línea -- 2 líneas fijas en vez de que la
   cantidad de líneas dependa de cuál se eligió. */
.pax-chip.anim.sel{ flex:1 1 100%; order:-1; padding:0 12px; background:var(--accent); }
/* Mismo tamaño de ícono que los chips de rango etario (Roy) -- antes eran
   más chicos (1rem contra 1.3rem), aunque el chip en sí (44px) siga siendo
   más chico que el de etario (52px). */
.pax-chip.anim .pax-chip-emoji{ font-size:1.3rem; line-height:1; flex:none; }
.pax-chip.anim .pax-chip-label{ font-size:.72rem; font-weight:800; overflow:hidden; text-overflow:ellipsis; }
.pax-chip.anim:not(.sel) .pax-chip-label{ display:none; }

.emoji-chip.anim{ flex:0 0 52px; height:52px; padding:0; border-radius:999px; background:var(--input); }
/* Roy: en etario (a diferencia de participación) NO quiere que el
   seleccionado salte al inicio -- pero como estos botones también llevan
   la clase .pax-chip (ver HTML de #chips-etario), sin este order:0
   heredaban el order:-1 de la regla de arriba. Sigue expandiéndose en su
   lugar (flex:1 1 auto), solo que sin reordenarse. */
.emoji-chip.anim.sel{ flex:1 1 auto; order:0; padding:0 14px; background:var(--accent); }
.emoji-chip.anim .pax-chip-emoji{ font-size:1.3rem; line-height:1; flex:none; }
.emoji-chip.anim .pax-chip-label{ font-size:.78rem; font-weight:800; overflow:hidden; text-overflow:ellipsis; }
.emoji-chip.anim:not(.sel) .pax-chip-label{ display:none; }

/* Urgencia: naranja reservado a "Urgente" (único color con significado
   clínico fijo), Pronta/Programada en sage -- las 3 siempre muestran label. */
.urg-row{ display:flex; gap:5px; }
/* Mismo alto que #btnGuardar (54px) -- Roy: "que los botones de tipo de
   resolución tengan el mismo alto que el botón guardar". */
.urg-chip{ flex:1; height:54px; border-radius:11px; border:1.5px solid var(--inputBd); background:var(--input); color:var(--chipTxt); display:flex; align-items:center; justify-content:center; gap:5px; padding:0 4px; font-size:.78rem; font-weight:700; box-shadow:none; margin:0; transition:background .13s,border-color .13s,color .13s; }
.urg-chip span:first-child{ font-size:.85rem; }
.urg-chip.sel[data-urgencia="Urgente"]{ background:var(--urgente); border-color:var(--urgente); color:#fff; }
.urg-chip.sel[data-urgencia="Pronta"], .urg-chip.sel[data-urgencia="Programada"]{ background:var(--sage); border-color:var(--sage); color:#1C231B; }

/* Barra "vas a guardar" + botón grande de deshacer con cuenta regresiva */
/* Barra fija al fondo (resumen "vas a guardar" + botón Guardar) -- sticky
   respeta el contenedor con scroll que corresponda (body en el celu real,
   #app en el marco de desktop), y como .screen.active ya viene con padding
   lateral, alcanza con neutralizarlo acá para que la barra llegue de punta a
   punta. background sólido para que el contenido de arriba no se transparente
   al scrollear detrás. */
/* margin-top:auto -- con .screen.active ahora siendo flex:1 (más arriba),
   esto empuja la barra al fondo cuando sobra espacio (Roy: "que quede abajo,
   fijo... prefiero que quede arriba del botón el espacio muerto"). Sigue con
   position:sticky para pantallas con mucho contenido (Problemas), donde no
   sobra espacio para empujar -- ahí sticky es lo que mantiene el botón
   alcanzable sin scrollear hasta el final. Los dos conviven bien: sticky
   solo actúa sobre la posición "de reposo" que ya dejó el margin-top:auto. */
.save-bar{ position:sticky; bottom:0; z-index:20; background:var(--bg); margin:auto -12px 0; padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px)); box-shadow:0 -6px 14px rgba(0,0,0,.08); }
.resumen-guardar{ display:flex; align-items:center; gap:6px; margin:0 0 6px; min-height:16px; }
.resumen-guardar-label{ font-size:.68rem; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); flex:none; }
.resumen-guardar-txt{ flex:1; font-size:.85rem; font-weight:600; color:var(--ph); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.resumen-guardar-txt.completo{ color:var(--text); }
/* Pálido hasta que falten diagnóstico/etario/urgencia/lugar (misma señal que
   el texto de arriba), vuelve al verde normal apenas está todo -- sigue
   siendo tocable en el estado pálido (guardar() explica qué falta si lo
   apretás antes de tiempo), esto es puro feedback visual. */
#btnGuardar, #btnGuardarPractica{ height:54px; padding:0; display:flex; align-items:center; justify-content:center; background:var(--muted); opacity:.55; transition:background .2s,opacity .2s,box-shadow .15s,transform .08s; }
#btnGuardar.ready, #btnGuardarPractica.ready{ background:var(--accent); opacity:1; }

/* Un toque más grande que antes (56px -> 64px, Roy). Mismo botón para
   Problemas (#btnDeshacer) y Prácticas (#btnDeshacerPrac, mismo patrón
   visual reusado tal cual). */
#btnDeshacer, #btnDeshacerPrac{ position:relative; overflow:hidden; display:flex; align-items:center; gap:10px; padding:0 14px; height:64px; border-radius:16px; background:var(--urgente); color:#fff; border:none; box-shadow:0 4px 16px rgba(231,84,40,.4); text-align:left; }
#btnDeshacer .undo-icon, #btnDeshacerPrac .undo-icon{ position:relative; z-index:1; font-size:1.3rem; line-height:1; flex:none; }
#btnDeshacer .undo-text, #btnDeshacerPrac .undo-text{ position:relative; z-index:1; flex:1; font-weight:800; font-size:.95rem; display:flex; flex-direction:column; gap:1px; }
#btnDeshacer .undo-sub, #btnDeshacerPrac .undo-sub{ font-weight:400; font-size:.72rem; opacity:.9; }
#btnDeshacer .undo-timer, #btnDeshacerPrac .undo-timer{ position:relative; z-index:1; flex:none; font-size:.78rem; font-weight:800; opacity:.95; background:rgba(255,255,255,.22); border-radius:999px; padding:5px 10px; }
#btnDeshacer:hover, #btnDeshacerPrac:hover{ box-shadow:0 4px 16px rgba(231,84,40,.4); }
/* Cubre TODO el botón, no solo una tira abajo (Roy: "que abarque todo el
   botón") -- arranca en todo el ancho y se achica hacia la izquierda a lo
   largo de los 10s de la ventana de deshacer (misma ventana para Problemas
   y Prácticas ahora), dejando ver el naranja liso detrás a medida que pasa
   el tiempo. Va primera en el HTML a propósito (position:absolute, así que
   no importa el orden para el layout) para que el ícono/texto/timer -- con
   z-index:1 -- queden siempre legibles por encima. Se recrea de cero cada
   vez que se guarda (ver _restoreUndoBtn/_restoreUndoBtnPrac), así que la
   animación siempre arranca en sync con el timestamp real. */
#btnDeshacer .undo-progress, #btnDeshacerPrac .undo-progress{ position:absolute; inset:0; background:rgba(255,255,255,.28); transform-origin:left; animation:undoDrain 10s linear forwards; }
@keyframes undoDrain{ from{ transform:scaleX(1); } to{ transform:scaleX(0); } }

/* ===== Rediseño Historial ("Tus cargas", mockup de Roy) ===== */
/* Pestañas Avance/Autonomía/Tendencias de Resumen -- SOLO Resumen (el filtro
   de Historial tiene su propia clase, .hist-tipo-track, más abajo; y "Ver
   10/30" pisa todo esto con .seg-control-sm). Pista blanca rectangular
   (Roy), la elegida se rellena de verde oscuro, también rectangular, con
   un margen chico contra el borde de la pista. */
.seg-control{ display:flex; gap:0; padding:3px; background:var(--input); border:1.5px solid var(--inputBd); border-radius:12px; }
.seg-control-btn{ flex:1; height:38px; display:flex; align-items:center; justify-content:center; border-radius:9px; border:none; background:transparent; color:var(--chipTxt); font-weight:700; font-size:.85rem; margin:0; width:auto; padding:0 10px; box-shadow:none; transition:background .15s,color .15s; }
.seg-control-btn.sel{ background:var(--accent); color:var(--accentFg); }
/* Roy: en Gestión, Admin ve Altas/Docentes/Residentes/Lugares/Huecos AP/
   Bugs -- 6 pestañas, no entran apretadas por igual (.seg-control-btn
   normal, flex:1) sin achicar el texto de más ("Huecos AP" se cortaba).
   Scrollea en vez de apretar, mismo criterio que .bottom-nav -- pero
   "solo en Admin nomás" (Roy): la clase .gest-subtabs-scroll se agrega por
   JS únicamente cuando g.es_admin_bugs (renderGestion), así que el resto
   de los docentes (5 pestañas, sin Bugs) sigue con el reparto de siempre,
   sin scroll ni cambios. */
#gestSubTabRow.gest-subtabs-scroll{ overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch; }
#gestSubTabRow.gest-subtabs-scroll .seg-control-btn{ flex:0 0 auto; white-space:nowrap; }

/* Todos/Problemas/Prácticas (Historial, mockup nuevo de Roy): pista
   rectangular verde pálida, con las opciones adentro también rectangulares
   (no píldora) -- a diferencia de Resumen de arriba. Sin elegir no tienen
   borde propio (no se sienten "botón" al tocarlas), solo la elegida se
   rellena de verde oscuro, también rectangular, con un margen chico contra
   la pista (padding en el contenedor) para que se vea como flotando adentro. */
.hist-tipo-track{ display:flex; gap:0; padding:3px; background:rgba(var(--accent-rgb),.15); border:none; border-radius:12px; }
.hist-tipo-btn{ flex:1; height:38px; display:flex; align-items:center; justify-content:center; border-radius:9px; border:none; background:transparent; color:var(--chipTxt); font-weight:700; font-size:.85rem; margin:0; width:auto; padding:0 10px; box-shadow:none; transition:background .15s,color .15s; }
.hist-tipo-btn.sel{ background:var(--accent); color:var(--accentFg); }

/* "Ver 10/30" (mockup nuevo de Roy): un solo bloque blanco rectangular, las
   dos opciones adentro divididas por una línea recta (no un gap ni cajas
   separadas) -- overflow:hidden + radio en el contenedor redondea solo las
   puntas (rectangular, no píldora), cada botón queda cuadrado adentro y la
   línea divisoria es el borde entre los dos. La elegida se rellena de verde. */
.seg-control-sm{ background:var(--input); border:1.5px solid var(--inputBd); padding:0; gap:0; overflow:hidden; border-radius:9px; display:inline-flex; }
.seg-control-sm .seg-control-btn{ flex:none; width:40px; height:32px; font-size:.85rem; padding:0; border-radius:0; border:none; background:transparent; }
.seg-control-sm .seg-control-btn:first-child{ border-right:1.5px solid var(--inputBd); }
.seg-control-sm .seg-control-btn.sel{ background:var(--accent); color:var(--accentFg); }
/* Botón "Imprimir" al lado del buscador, mismo alto que el input (Roy) --
   el contenedor tiene align-items:stretch, pero el emoji 🖨️ infla la
   line-box del botón más que el texto del input, así que si el padding
   vertical del botón es igual o mayor al del input, termina siendo el ítem
   más alto de la fila y ESTIRA al input en vez de igualarlo. Con padding
   chico + line-height:1 el botón queda más bajo que el input de entrada, y
   ahí sí el stretch lo sube a la altura real del input (no al revés). */
.hist-print-btn{ flex:none; display:flex; align-items:center; justify-content:center; gap:6px; padding:8px 14px; line-height:1; border-radius:14px; border:2px solid var(--inputBd); background:var(--input); color:var(--chipTxt); font-weight:700; font-size:.85rem; white-space:nowrap; box-shadow:none; margin:0; width:auto; box-sizing:border-box; }
.hist-print-btn:hover{ background:rgba(0,0,0,.05); box-shadow:none; }
body.dark .hist-print-btn:hover{ background:rgba(255,255,255,.06); }

.hist-card{ background:var(--panelBg); border:1px solid var(--panelBd); border-radius:16px; padding:14px; margin:10px 0; box-shadow:var(--shadow-sm); }
.hist-card-head{ display:flex; align-items:center; gap:8px; }
.hist-card-icon{ flex:none; font-size:1.2rem; }
.hist-card-title{ flex:1; min-width:0; font-weight:800; font-size:1rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hist-card-badges{ flex:none; font-size:.9rem; display:flex; gap:2px; }
.hist-card-date{ flex:none; font-size:.72rem; color:var(--muted); font-weight:700; }
.hist-card-meta{ display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.hist-tag{ display:inline-flex; align-items:center; gap:4px; font-size:.78rem; color:var(--chipTxt); background:var(--panelHdr); border-radius:999px; padding:4px 10px; font-weight:600; }
.hist-cant{ display:inline-flex; align-items:center; font-size:.78rem; color:var(--accent); background:rgba(var(--accent-rgb),.14); border-radius:999px; padding:4px 10px; font-weight:800; transition:background .15s,color .15s,transform .15s; }
/* Se prende un instante al tocar "+1 de nuevo" (Roy: "que se resalte el
   x2/x3... para evidenciar que se está sumando"), después vuelve solo al
   estilo normal de arriba (la transition de .hist-cant hace el desvanecido). */
.hist-cant.hist-cant-flash{ background:var(--urgente); color:#fff; transform:scale(1.15); }
.hist-nota{ display:flex; gap:8px; margin-top:8px; padding:9px 11px; background:var(--input); border-radius:12px; font-size:.82rem; line-height:1.4; color:var(--text); }
.hist-nota-icon{ flex:none; opacity:.7; }
.hist-actions-row{ display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }
/* +1/Guardar/Cancelar (Historial y Notas, comparten esta clase) -- mismo
   borde/relleno que .urg-chip (Roy: blanco/rectangular, no transparente/
   pill), sin estado "sel" porque son acciones, no una elección persistente.
   Editar/Borrar de Notas ya no usan esta clase -- ver .icon-btn en
   renderNotas (Roy: "en la misma línea... como en la pantalla problemas"). */
.hist-action-btn{ flex:1; min-width:90px; height:38px; margin:0; padding:0 10px; border-radius:11px; border:1.5px solid var(--inputBd); background:var(--input); color:var(--chipTxt); font-weight:700; font-size:.78rem; box-shadow:none; }
.hist-action-btn:hover{ background:rgba(0,0,0,.05); box-shadow:none; }
body.dark .hist-action-btn:hover{ background:rgba(255,255,255,.06); }
.hist-action-btn.danger{ color:var(--danger); border-color:rgba(59,19,20,.25); }
body.dark .hist-action-btn.danger{ border-color:rgba(201,138,126,.35); }

/* Modo edición inline -- reemplaza el cuerpo de la tarjeta mientras se edita
   (lugar/cantidad/nota nomás, ver comentario en la migración 0040 sobre por
   qué no se edita el diagnóstico/práctica en sí). */
.hist-edit-row{ display:flex; gap:8px; margin-top:8px; }
.hist-edit-row input, .hist-edit-row textarea{ margin-top:0; }

/* ===== Rediseño Mis Notas (mockup de Roy) ===== */
.notas-add-btn{ display:flex; align-items:center; justify-content:center; gap:8px; width:100%; padding:15px 16px; border-radius:14px; border:2px dashed var(--inputBd); background:transparent; color:var(--accent); font-weight:700; font-size:.95rem; margin:.6em 0 0; box-shadow:none; }
.notas-add-btn:hover{ background:rgba(var(--accent-rgb),.06); box-shadow:none; }

/* ===== Rediseño Resumen (antes "Feedback", mockups de Roy: Avance/Autonomía/Tendencias) ===== */
#screen-feedback .fb-header{ margin:.2em 0 12px; }
#screen-feedback .fb-tabs{ margin-bottom:8px; }
.fb-stat-row{ margin-bottom:10px; }
.fb-vertodas-link{ display:inline-block; width:auto; margin:6px 0 4px; padding:0; background:none; border:none; box-shadow:none; color:var(--accent); font-weight:700; font-size:.85rem; text-align:left; }
.fb-vertodas-link:hover{ text-decoration:underline; background:none; box-shadow:none; }
/* Gestión > Altas (Roy: "quiero que se distingan los títulos de los
   textos") -- .sect-label-txt y el <small> de acá abajo (texto del QR,
   "Sin solicitudes pendientes.") compartían el mismo var(--muted), se leían
   igual. Acá el texto pasa a --text (más oscuro/legible); el título sigue
   en --muted + mayúsculas + chico -- se diferencian por color Y por forma. */
#gestTabAltas small{ color:var(--text); opacity:.85; }
/* Gestión > Residentes (Roy, mockup): "Agregar residente" entero en un
   cuadro blanco. */
.gest-card-blanco{ background:var(--input); border:1.5px solid var(--inputBd); border-radius:14px; padding:14px; }
.gest-card-blanco input, .gest-card-blanco select{ margin-top:0; }
/* Botón "+ Agregar" más chico (Roy) -- pisa el <button> base grande. */
.gest-btn-chico{ padding:12px; font-size:.95rem; }
/* Selector de nivel de "Agregar residente": rectángulos, no píldoras, sin
   borde en ninguno de los dos estados (Roy: "rectángulos uno al lado del
   otro sin bordes") -- seleccionado relleno, el resto texto plano. Radio
   chico (6px) en vez del 999px de .pax-chip para que se lean como
   rectángulos, no como pastillas. */
.gest-nivel-rect{ display:flex; gap:6px; }
.gest-nivel-rect .pax-chip{ flex:1; text-align:center; border:none; background:transparent; border-radius:6px; padding:9px 4px; }
.gest-nivel-rect .pax-chip.sel{ background:var(--accent); color:var(--accentFg); }
/* Chips de nivel de "Gestionar residentes": fondo blanco en los dos estados
   (Roy: "que tengan fondo blanco"), mismo trato que Cohorte en Estadísticas. */
.gest-nivel-blanco .pax-chip{ background:#fff; }
body.dark .gest-nivel-blanco .pax-chip{ background:rgba(255,255,255,.08); }
.gest-nivel-blanco .pax-chip.sel{ background:var(--accent); }
/* Contador de Estado: mismas tarjetas .stats-kpi-card de Estadísticas:
   acá además son tappable, el borde se resalta en la que está activa. */
.gest-estado-card{ cursor:pointer; transition:border-color .13s,box-shadow .13s; }
.gest-estado-card.sel{ border-color:var(--accent); box-shadow:0 0 0 1.5px var(--accent) inset; }
/* Botones de la tarjeta expandida: más chicos y con borde suave (Roy) --
   antes eran .secondary (borde 2px del color de acento); acá el borde pasa
   a ser el mismo gris tenue que ya usan los inputs, no un color fuerte. */
.gest-action-btn{ flex:1; min-width:110px; margin:0; padding:9px 10px; font-size:.8rem; font-weight:700; border:1.5px solid var(--inputBd); border-radius:10px; background:transparent; color:var(--text); box-shadow:none; }
/* Lápiz de "editar nombre" al lado del nombre (Roy) -- chico, sin fondo,
   solo aparece con la tarjeta abierta. */
.gest-lapiz{ flex:none; width:auto; margin:0; padding:0 2px; background:none; border:none; box-shadow:none; font-size:.85rem; line-height:1; }
/* Gestión > Lugares (mockup de Roy): "Editar"/"Baja" como texto-link, no
   botones -- fila más liviana que la de Residentes (acá no hay tarjeta
   expandible, es solo nombre + 2 acciones). */
.gest-row-link{ flex:none; width:auto; margin:0; padding:0; background:none; border:none; box-shadow:none; font-weight:700; font-size:.85rem; }
.gest-row-link.editar, .gest-row-link.reactivar{ color:var(--accent); }
.gest-row-link.baja{ color:var(--danger); }
/* El encabezado "Filtrar por período y lugar" del sheet, blanco de verdad
   (Roy) -- no el tinte gris-verdoso (--panelHdr) que llevan los demás
   headers de sheet de la app, esto es solo para este. */
#fb-filtro-panel .panel-header{ background:#fff; }
body.dark #fb-filtro-panel .panel-header{ background:var(--panelBg); }
/* La X mantiene el gris que tenía el header antes (Roy) -- si no, contra el
   blanco nuevo del header queda invisible. */
#fb-filtro-panel .panel-close{ background:var(--panelHdr); border-radius:10px; }
/* Botón "Filtrar" junto al título "Carga en el tiempo" (mockup de Roy) --
   abre el mismo sheet de período+lugar de siempre. Se resalta en verde
   cuando hay un filtro activo (antes lo mostraba como texto). */
.fb-filtrar-btn{ flex:none; margin:0 0 0 auto; width:auto; display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 14px; border-radius:999px; border:1.5px solid var(--inputBd); background:var(--input); color:var(--chipTxt); font-weight:700; font-size:.78rem; box-shadow:none; }
.fb-filtrar-btn.activo{ background:var(--accent); border-color:var(--accent); color:var(--accentFg); }
/* Chips de período dentro del sheet de Tendencias (Roy): repartidos en todo
   el ancho (3 por fila) y sin recuadro -- solo .pax-chip acá, el resto de
   la app sigue con el borde normal. */
.fb-periodo-chips .pax-chip{ flex:1 1 28%; border:none; text-align:center; }
.fb-todas-wrap{ margin:4px 0 8px; }

/* "Evolución por año de residencia" (mockup de Roy): antes era un <details>
   colapsable, ahora queda fija al pie de la pestaña Autonomía, como una
   tarjeta aparte. */
.fb-nivel-card{ background:var(--panelBg); border:1px solid var(--panelBd); border-radius:16px; padding:16px; margin-top:18px; box-shadow:var(--shadow-sm); }
.fb-nivel-title{ margin:0; color:var(--accent); font-size:1.02rem; }
.fb-nivel-sub{ margin:4px 0 0; font-size:.8rem; opacity:.75; }
.fb-nivel-estado-leyenda{ display:flex; gap:14px; flex-wrap:wrap; margin:12px 0 4px; font-size:.75rem; color:var(--chipTxt); }
.fb-nivel-estado-leyenda span{ display:inline-flex; align-items:center; gap:5px; }
/* Punto de estado por año: relleno = año en curso, hueco = ya cursado,
   punteado = todavía no llegás ahí. */
.fb-nivel-dot{ width:11px; height:11px; border-radius:50%; flex:none; display:inline-block; box-sizing:border-box; }
.fb-nivel-dot.fb-dot-actual{ background:var(--accent); border:2px solid var(--accent); }
.fb-nivel-dot.fb-dot-cursado{ background:transparent; border:2px solid var(--accent); }
.fb-nivel-dot.fb-dot-futuro{ background:transparent; border:2px dashed var(--inputBd); }
.fb-nivel-row{ display:flex; align-items:center; gap:8px; margin:8px 0; }
/* El año (R1-R4) va envuelto en una píldora, no separado en punto+texto
   (Roy) -- lleva el mismo estado que el punto de arriba (relleno/hueco/
   punteado), ahora aplicado a la propia píldora. */
.fb-nivel-badge{ flex:none; display:inline-flex; align-items:center; justify-content:center; min-width:34px; height:24px; padding:0 9px; border-radius:999px; font-size:.74rem; font-weight:800; box-sizing:border-box; }
.fb-nivel-badge.fb-badge-actual{ background:var(--accent); color:var(--accentFg); border:2px solid var(--accent); }
.fb-nivel-badge.fb-badge-cursado{ background:transparent; color:var(--chipTxt); border:2px solid var(--inputBd); }
.fb-nivel-badge.fb-badge-futuro{ background:transparent; color:var(--muted); border:2px dashed var(--inputBd); }
/* "Sin registros"/"Aún no cursado": mismo rectángulo redondeado que la
   barra real (.fb-nivel-bar), con el estilo de línea que le corresponde --
   continua para cursado/actual sin cargas, punteada para futuro (Roy). */
/* Mismo alto que .fb-nivel-badge (Roy) -- antes 18px, se veía más bajo que
   el óvalo de R1/R2/etc. */
.fb-nivel-empty{ flex:1; height:24px; border-radius:6px; display:flex; align-items:center; padding:0 10px; font-size:.72rem; opacity:.7; font-style:italic; box-sizing:border-box; min-width:0; }
.fb-nivel-empty.fb-empty-solid{ border:1.5px solid var(--inputBd); }
.fb-nivel-empty.fb-empty-dashed{ border:1.5px dashed var(--inputBd); }
.fb-nivel-bar{ flex:1; height:18px; border-radius:6px; overflow:hidden; display:flex; min-width:0; }
/* min-width fijo (Roy): así el placeholder vacío que va en las filas sin
   datos reserva el mismo lugar que ocupa "N cargas" en las filas con
   datos, y las barras/rectángulos quedan del mismo ancho en todas las filas. */
.fb-nivel-total{ flex:none; min-width:52px; font-size:.72rem; opacity:.7; white-space:nowrap; text-align:right; }
/* Referencias de participación: 2 columnas x 2 filas, círculo como
   referencia de color (Roy), no cuadrado. */
/* Deshecho el cambio a fila-que-envuelve (Roy: quedaba 3+1, prefería la
   grilla fija 2x2 de antes). */
.fb-partic-leyenda{ display:grid; grid-template-columns:1fr 1fr; gap:6px 14px; margin-top:8px; font-size:.75rem; color:var(--chipTxt); }
.fb-partic-leyenda > div{ display:inline-flex; align-items:center; gap:6px; }
.fb-partic-leyenda > div > span{ width:11px; height:11px; border-radius:50%; display:inline-block; flex:none; }

/* ===== Rediseño Estadísticas (docentes, mockup de Roy: sub-pestaña "General") ===== */
/* Tarjetas 2x2 de Activos/Cargas totales/Prom. por residente/Con carga esta
   semana -- mismo blanco+borde fino que ya se usa en Resumen (.fb-header
   etc.), con un emoji arriba del número en vez de color de fondo. */
.stats-kpi-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:8px; }
/* Variante de 3 columnas -- Cobertura de AP/Prácticas del cohorte
   (Completas/En curso/Sin iniciar), mismo look de tarjeta. */
.stats-kpi-grid-3{ grid-template-columns:repeat(3,1fr); }
/* Variante de 4 columnas -- conteo de Docentes/JR/IR/CL en Gestión. */
.stats-kpi-grid-4{ grid-template-columns:repeat(4,1fr); gap:6px; }
.stats-kpi-grid-4 .stats-kpi-card{ padding:8px 4px; }
.stats-kpi-grid-4 .stats-kpi-valor{ font-size:1.25rem; }
.stats-kpi-card{ background:var(--input); border:1.5px solid var(--inputBd); border-radius:14px; padding:10px 10px; text-align:center; }
.stats-kpi-valor{ font-size:1.5rem; font-weight:800; color:var(--text); font-variant-numeric:tabular-nums; }
.stats-kpi-label{ font-size:.72rem; opacity:.7; margin-top:2px; }
