/* PANEL — la capa de componentes de las pantallas con sesión.
 *
 * PASE 1 de la rehabilitación de portales (27 de agosto de 2026).
 *
 * Qué es y qué NO es. No es un sistema de diseño nuevo: `tokens.css` ya es la
 * capa de tokens de la casa (color, tipografía, escala, radios, foco) y las
 * tres pantallas con sesión —panel, portal y tablero— ya la cargan. Lo que
 * faltaba era la capa de COMPONENTES: cada pantalla tenía su propia tarjeta,
 * su propia tabla, su propia píldora de estado y su propio formato de dinero.
 * Aquí viven una sola vez, construidas SOLO con esos tokens.
 *
 * Todo va con prefijo `p-` a propósito. Las clases viejas (.caja, .boton,
 * .vacia/.vacío, .kpi) siguen vivas en admin.html y consulta.html; redefinirlas
 * desde aquí cambiaría dos pantallas que hoy funcionan, en silencio y por
 * cascada. Lo nuevo nace en `p-`, y cada pase migra su propia pantalla a mano.
 *
 * Los tres roles comparten los componentes y NO la densidad:
 *   practicante → enfocado y clínico   (.p-app.enfocado)
 *   admin       → denso y operativo    (.p-app.denso)
 *   paciente    → simple y tranquilo   (.p-app.calmo)
 * La densidad solo mueve escalas y aire; nunca cambia el significado de nada.
 */

/* ══════════════════════════════ armazón ══════════════════════════════ */

.p-app{
  --p-aire: var(--e5);          /* el aire de la densidad; se re-declara abajo */
  --p-lado: 232px;
  display:grid;
  grid-template-columns: var(--p-lado) minmax(0,1fr);
  min-height:100vh;
  background:var(--bg);
  color:var(--fg);
  font-family:var(--texto);
  font-size:var(--t-base);
}
.p-app.denso{ --p-aire: var(--e4); --p-lado: 216px; }
.p-app.calmo{ --p-aire: var(--e6); }

/* La columna del rol: marca, navegación, salida. */
.p-lado{
  border-right:1px solid var(--linea);
  background:var(--superficie);
  padding:var(--e5) var(--e4);
  display:flex; flex-direction:column; gap:var(--e5);
}
.p-marca{font-family:var(--display);font-size:17px;letter-spacing:.24em;text-transform:uppercase;line-height:1.2}
.p-marca span{display:block;font-family:var(--texto);font-size:9px;letter-spacing:.3em;
  color:var(--acento-suave);margin-top:4px}
.p-nav{display:flex;flex-direction:column;gap:2px}
.p-nav a, .p-nav button{
  display:flex;align-items:center;justify-content:space-between;gap:var(--e2);
  width:100%;text-align:left;padding:10px 12px;border:0;background:none;
  border-radius:9px;font:inherit;font-size:var(--t-chico);color:var(--fg-suave);
  text-decoration:none;cursor:pointer;transition:background var(--paso),color var(--paso);
}
.p-nav a:hover, .p-nav button:hover{background:var(--acento-lavado);color:var(--fg)}
.p-nav a.on, .p-nav button.on{background:var(--fg);color:var(--superficie)}
.p-nav .p-cuenta{
  font-size:var(--t-micro);font-variant-numeric:tabular-nums;
  background:var(--acento-lavado);color:var(--acento);border-radius:var(--r-pastilla);
  padding:2px 7px;min-width:20px;text-align:center;
}
.p-nav a.on .p-cuenta, .p-nav button.on .p-cuenta{background:rgba(255,255,255,.22);color:var(--blanco)}
.p-lado-pie{margin-top:auto;display:flex;flex-direction:column;gap:var(--e2)}

.p-cuerpo{padding:var(--p-aire);min-width:0}
.p-ancho{max-width:1120px;margin:0 auto}
.p-app.calmo .p-ancho{max-width:760px}

/* Encabezado de página: título, contexto y acciones en un solo renglón. */
.p-cabeza{
  display:flex;justify-content:space-between;align-items:flex-end;gap:var(--e4);
  flex-wrap:wrap;margin-bottom:var(--e5);
}
.p-cabeza h1{font-family:var(--display);font-weight:500;font-size:var(--t-h2);line-height:1.1;
  margin:0;text-wrap:balance}
.p-cabeza .p-contexto{color:var(--fg-suave);font-size:var(--t-chico);margin-top:6px}
.p-acciones{display:flex;gap:var(--e2);flex-wrap:wrap}

.p-seccion{
  font-size:var(--t-micro);letter-spacing:var(--track-versalita);text-transform:uppercase;
  color:var(--fg-tenue);margin:var(--e6) 0 var(--e3);
}
.p-seccion:first-child{margin-top:0}

/* Teléfono y tableta: la columna del rol se vuelve barra de arriba. */
/* Excepción al juego canónico (560/760/1160): La banda 760-860 del portal clínico necesita una sola columna; a 759 la perdería
   y la ficha saldría en dos columnas de nada. */
@media (max-width:860px){
  .p-app{grid-template-columns:1fr}
  .p-lado{
    border-right:0;border-bottom:1px solid var(--linea);
    flex-direction:row;align-items:center;gap:var(--e4);
    padding:var(--e3) var(--e4);overflow-x:auto;
  }
  .p-nav{flex-direction:row;gap:4px}
  .p-nav a, .p-nav button{white-space:nowrap;padding:8px 11px}
  .p-lado-pie{margin-top:0;flex-direction:row}
  .p-cuerpo{padding:var(--e4)}
}

/* ══════════════════════════════ tarjetas ══════════════════════════════ */

.p-caja{
  background:var(--superficie);border:1px solid var(--linea);
  border-radius:var(--r-caja);padding:var(--e4) var(--e5);
}
.p-app.denso .p-caja{padding:var(--e4)}
.p-caja-t{
  font-size:var(--t-micro);letter-spacing:var(--track-versalita);text-transform:uppercase;
  color:var(--fg-tenue);margin-bottom:var(--e3);
}
.p-caja-pie{
  margin-top:var(--e3);padding-top:var(--e3);border-top:1px solid var(--linea-tenue);
  font-size:var(--t-chico);color:var(--fg-suave);
}
/* Prosa dentro de una caja. Nació porque dos pantallas la pidieron por su
   cuenta —ventas y empresas— escribiendo `p-nota` sin que existiera: cuando
   dos autores inventan la misma clase, el hueco es de la capa compartida y no
   de ellos. */
.p-nota{
  font-size:var(--t-chico);color:var(--fg-suave);line-height:1.55;
  margin:var(--e2) 0 0;
}
.p-nota:first-child{margin-top:0}
.p-nota strong{color:var(--fg);font-weight:600}

.p-lista{
  margin:var(--e2) 0 0;padding-left:1.1em;
  font-size:var(--t-chico);color:var(--fg-suave);line-height:1.55;
}
.p-lista li{margin-bottom:var(--e2)}
.p-lista li:last-child{margin-bottom:0}
.p-lista strong{color:var(--fg);font-weight:600}

/* Una liga larga junto al botón que la copia. `min-width:0` sobre el <code> es
   lo que impide que una URL larga —que no tiene dónde partirse— estire la caja
   y saque al botón de la pantalla en un teléfono. */
.p-liga-caja{
  display:flex;gap:var(--e3);align-items:center;
  margin:var(--e3) 0;padding:var(--e3);
  background:var(--bg);border:1px solid var(--linea);border-radius:var(--r-caja);
}
.p-liga-caja code{
  flex:1 1 auto;min-width:0;overflow-x:auto;white-space:nowrap;
  font-size:var(--t-micro);color:var(--fg);
}
.p-liga-caja .p-boton{flex:0 0 auto}
@media (max-width:559px){
  .p-liga-caja{flex-direction:column;align-items:stretch}
  .p-liga-caja .p-boton{width:100%}
}

.p-rejilla{display:grid;gap:var(--e3)}
.p-rejilla.dos{grid-template-columns:repeat(2,minmax(0,1fr))}
.p-rejilla.tres{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:759px){
  .p-rejilla.dos,.p-rejilla.tres{grid-template-columns:1fr}
}

/* ══════════════════════════ métricas compactas ══════════════════════════
   El brief lo pide por su nombre: nada de tarjetas enormes para números
   diminutos. El rótulo va ARRIBA (se lee antes de la cifra) y la cifra en
   DM Sans, no en display: es un dato funcional, no un adorno. */

.p-metricas{display:grid;gap:var(--e3);grid-template-columns:repeat(4,minmax(0,1fr))}
.p-metricas.tres{grid-template-columns:repeat(3,minmax(0,1fr))}
.p-metricas.dos{grid-template-columns:repeat(2,minmax(0,1fr))}
/* Excepción al juego canónico (560/760/1160): La reja de dos columnas del portal se mide contra el riel lateral, no contra el
   ancho de la ventana. */
@media (max-width:1080px){.p-metricas{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:559px){.p-metricas,.p-metricas.tres,.p-metricas.dos{grid-template-columns:1fr}}

.p-metrica{
  background:var(--superficie);border:1px solid var(--linea);
  border-radius:var(--r-caja);padding:var(--e4);display:flex;flex-direction:column;
}
.p-metrica .r{
  font-size:var(--t-micro);letter-spacing:.13em;text-transform:uppercase;
  color:var(--fg-tenue);min-height:2.2em;margin-bottom:var(--e2);
}
.p-metrica .v{font-size:27px;font-weight:600;line-height:1.05;letter-spacing:-.01em}
.p-metrica .v small{font-size:15px;font-weight:500;color:var(--fg-suave)}
.p-metrica .d{font-size:12px;margin-top:6px;color:var(--fg-suave);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.p-metrica .d.sube{color:var(--ok)}
.p-metrica .d.baja{color:var(--aviso)}
/* «Estimado» y sus parientes: lo que no es un hecho se dice que no lo es. */
.p-metrica .n{font-size:11px;color:var(--fg-tenue);margin-top:4px}
.p-metrica[data-nota]{position:relative}

/* ══════════════════════════════ tablas ══════════════════════════════ */

.p-marco{overflow-x:auto;border:1px solid var(--linea);border-radius:var(--r-caja);
  background:var(--superficie)}
.p-tabla{width:100%;border-collapse:collapse;font-size:var(--t-chico)}
.p-tabla th{
  font-size:var(--t-micro);letter-spacing:.14em;text-transform:uppercase;font-weight:500;
  color:var(--fg-tenue);text-align:left;padding:12px 16px;
  border-bottom:1px solid var(--linea);background:var(--superficie-baja);white-space:nowrap;
}
.p-tabla td{padding:13px 16px;border-bottom:1px solid var(--linea-tenue);vertical-align:top}
.p-app.denso .p-tabla td{padding:10px 14px}
.p-tabla tr:last-child td{border-bottom:0}
.p-tabla tbody tr.clic{cursor:pointer;transition:background var(--paso)}
.p-tabla tbody tr.clic:hover{background:var(--acento-lavado)}
.p-tabla .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.p-tabla td small{display:block;color:var(--fg-suave);font-size:12.3px;margin-top:2px}
.p-tabla .quien{font-weight:500}

/* ═══════════════════════ estados: forma, no solo color ═══════════════════════
   El brief lo exige: «do not rely solely on color». Cada estado lleva su
   glifo por ::before, así que se distingue en gris, impreso y con daltonismo. */

.p-estado{
  display:inline-flex;align-items:center;gap:5px;
  font-size:var(--t-micro);letter-spacing:.1em;text-transform:uppercase;font-weight:600;
  border-radius:var(--r-pastilla);padding:4px 10px;white-space:nowrap;
}
.p-estado::before{font-weight:400}
.p-estado.agendada    {background:var(--acento-lavado);color:var(--acento)}
.p-estado.agendada::before{content:"○"}
.p-estado.confirmada  {background:var(--ok-bg);color:var(--ok)}
.p-estado.confirmada::before{content:"✓"}
.p-estado.completada  {background:var(--ok-bg);color:var(--ok)}
.p-estado.completada::before{content:"✓✓"}
.p-estado.cancelada   {background:var(--linea-tenue);color:var(--fg-suave)}
.p-estado.cancelada::before{content:"✕"}
.p-estado.no-asistio  {background:var(--riesgo-bg);color:var(--riesgo)}
.p-estado.no-asistio::before{content:"—"}
.p-estado.pagado      {background:var(--ok-bg);color:var(--ok)}
.p-estado.pagado::before{content:"✓"}
.p-estado.pendiente   {background:var(--aviso-bg);color:var(--aviso)}
.p-estado.pendiente::before{content:"·"}
.p-estado.nueva       {background:var(--acento);color:var(--blanco)}
.p-estado.nueva::before{content:"★"}

.p-chip{
  display:inline-flex;align-items:center;gap:5px;font-size:12px;
  border:1px solid var(--linea);border-radius:var(--r-pastilla);padding:3px 10px;
  color:var(--fg-suave);white-space:nowrap;
}
.p-chip.ok{border-color:var(--ok-linea);color:var(--ok)}
.p-chip.falta{border-color:var(--aviso-linea);color:var(--aviso)}

/* ══════════════════════════════ botones ══════════════════════════════ */

.p-boton{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  font:inherit;font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  border:1px solid transparent;border-radius:var(--r-pastilla);
  padding:11px 22px;cursor:pointer;text-decoration:none;
  transition:background var(--paso),border-color var(--paso),color var(--paso);
}
.p-boton.lleno{background:var(--acento);color:var(--blanco)}
.p-boton.lleno:hover{background:var(--fg)}
.p-boton.linea{background:var(--superficie);border-color:var(--linea);color:var(--fg)}
.p-boton.linea:hover{border-color:var(--fg)}
.p-boton.callado{background:none;color:var(--fg-suave);padding:8px 10px;letter-spacing:.1em}
.p-boton.callado:hover{color:var(--fg)}
.p-boton.peligro{background:none;border-color:var(--riesgo-linea);color:var(--riesgo)}
.p-boton.peligro:hover{background:var(--riesgo-bg)}
.p-boton.chico{padding:8px 16px;font-size:11px;min-height:36px}
.p-boton.ancho{width:100%}
.p-boton[disabled]{opacity:.5;cursor:default}
.p-boton:focus-visible, .p-nav a:focus-visible, .p-nav button:focus-visible,
.p-campo input:focus-visible, .p-campo select:focus-visible, .p-campo textarea:focus-visible{
  outline:var(--foco-anillo) solid var(--foco);outline-offset:2px;
}

/* ══════════════════════════════ campos ══════════════════════════════ */

.p-campo{display:flex;flex-direction:column;margin-bottom:var(--e3)}
.p-campo label{
  font-size:var(--t-micro);letter-spacing:.15em;text-transform:uppercase;
  color:var(--fg-tenue);margin-bottom:6px;
}
.p-campo input, .p-campo select, .p-campo textarea{
  width:100%;min-height:44px;border:1px solid var(--linea);border-radius:10px;padding:10px 13px;
  font:inherit;font-size:var(--t-chico);line-height:1.3;background:var(--superficie);color:var(--fg);
  transition:border-color var(--paso);
}
.p-campo input:focus, .p-campo select:focus, .p-campo textarea:focus{border-color:var(--fg);outline:none}
/* El select sin su disfraz nativo: mismo trazo que el input y un chevrón de la casa. */
.p-campo select{
  appearance:none;-webkit-appearance:none;padding-right:34px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23776B80' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;
}
.p-campo input[type=checkbox], .p-campo input[type=radio]{width:auto;min-height:0;padding:0;accent-color:var(--acento)}
.p-campo textarea{min-height:96px;resize:vertical}
.p-pista{font-size:11.5px;color:var(--fg-suave);margin-top:6px}
.p-msg{font-size:var(--t-chico);margin-top:var(--e2)}
.p-msg.mal{color:var(--riesgo)}
.p-msg.bien{color:var(--ok)}

/* ═════════════════════════ atención requerida ═════════════════════════
   La regla del brief, en CSS: cada renglón trae su acción. Y cuando no hay
   nada, no se inventa nada — para eso está `.p-aldia`. */

.p-atencion{display:flex;flex-direction:column;gap:var(--e2)}
.p-aviso{
  display:flex;gap:var(--e3);align-items:flex-start;
  background:var(--superficie);border:1px solid var(--linea);
  border-left:3px solid var(--fg-tenue);border-radius:10px;padding:14px 16px;
}
.p-aviso.alta{border-left-color:var(--riesgo)}
.p-aviso.media{border-left-color:var(--aviso)}
.p-aviso.info{border-left-color:var(--acento-suave)}
.p-aviso .qué{flex:1;min-width:0;font-size:var(--t-chico)}
.p-aviso .qué small{display:block;color:var(--fg-suave);font-size:12.5px;margin-top:3px}
.p-aviso .p-boton{flex:none}
.p-aldia{
  display:flex;align-items:center;gap:10px;
  color:var(--ok);font-size:var(--t-chico);
  background:var(--ok-bg);border-radius:10px;padding:14px 16px;
}
.p-aldia::before{content:"✓";font-weight:600}

/* ══════════════════════ hoy: la línea del día ══════════════════════
   Practicante: sus citas de hoy. Admin: las de toda la clínica. Mismo
   componente, la hora como canaleta fija para que el ojo baje derecho. */

.p-hoy{display:flex;flex-direction:column}
.p-cita{
  display:grid;grid-template-columns:78px minmax(0,1fr) auto;gap:var(--e3);
  align-items:center;padding:var(--e3) 0;border-bottom:1px solid var(--linea-tenue);
}
.p-cita:last-child{border-bottom:0}
.p-cita .hora{
  font-variant-numeric:tabular-nums;font-size:var(--t-chico);font-weight:600;
}
.p-cita .hora small{display:block;font-weight:400;color:var(--fg-tenue);font-size:11px}
.p-cita .quién{min-width:0}
.p-cita .quién b{font-weight:500}
.p-cita .quién small{display:block;color:var(--fg-suave);font-size:12.5px;margin-top:2px}
.p-cita .marcas{display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.p-cita.pasada{opacity:.55}
.p-cita.ahora{background:var(--acento-lavado);border-radius:10px;padding-inline:var(--e3)}
/* Excepción al juego canónico (560/760/1160): El riel lateral colapsado a 64px vive en 560-640: se mide contra el riel, no
   contra la página. */
@media (max-width:640px){
  .p-cita{grid-template-columns:64px minmax(0,1fr);row-gap:var(--e2)}
  .p-cita .marcas{grid-column:1/-1;justify-content:flex-start}
}

/* ══════════════════════════ capacidad ══════════════════════════
   Reservadas contra la meta semanal (D2: 20). La barra dice de un golpe
   quién está llena y quién tiene lugar. */

.p-capacidad{display:flex;flex-direction:column;gap:6px}
.p-capacidad .cifras{
  display:flex;justify-content:space-between;font-size:var(--t-chico);
  font-variant-numeric:tabular-nums;
}
.p-capacidad .cifras b{font-weight:600}
.p-capacidad .pista{height:7px;border-radius:var(--r-pastilla);background:var(--linea-tenue);overflow:hidden}
.p-capacidad .lleno{height:100%;border-radius:var(--r-pastilla);background:var(--acento);
  transition:width var(--paso)}
.p-capacidad.alta .lleno{background:var(--ok)}       /* ≥85%: llena */
.p-capacidad.baja .lleno{background:var(--aviso)}    /* <50%: hay lugar */

/* ══════════════════════════ vacíos y huesos ══════════════════════════
   Un vacío es información, no un hueco: dice qué falta y ofrece el paso. */

.p-vacio{
  text-align:center;padding:var(--e6) var(--e4);color:var(--fg-suave);
}
.p-vacio b{display:block;color:var(--fg);font-weight:500;font-size:var(--t-chico);margin-bottom:5px}
.p-vacio p{font-size:13px;max-width:44ch;margin:0 auto}
.p-vacio .p-boton{margin-top:var(--e4)}

.p-hueso{
  background:linear-gradient(90deg,var(--linea-tenue) 25%,var(--acento-lavado) 37%,var(--linea-tenue) 63%);
  background-size:400% 100%;border-radius:6px;height:14px;
  animation:p-brillo 1.4s ease-in-out infinite;
}
.p-hueso.alto{height:44px;border-radius:10px}
.p-hueso + .p-hueso{margin-top:8px}
.p-hueso.corto{width:55%}
@keyframes p-brillo{0%{background-position:100% 0}100%{background-position:0 0}}
@media (prefers-reduced-motion:reduce){
  .p-hueso{animation:none}
  .p-boton,.p-nav a,.p-nav button,.p-capacidad .lleno{transition:none}
}

/* ══════════════════════════ dato compacto ══════════════════════════
   Cuando hay poca historia NO se dibuja una gráfica enorme: se dice el
   número y, si acaso, una línea diminuta. La gráfica grande se gana. */

/* `.p-mini` nació como la chispa (barritas) y NADIE la usó así: ventas y el
   admin la escriben en veinte lugares como «texto chico y gris». Cada uno de
   esos renglones salía como una caja flex de 34 px con el texto pegado al
   piso. La clase pasa a significar lo que ya significaba en la práctica; la
   chispa se llama `.p-chispa`. */
.p-mini{font-size:12px;color:var(--fg-suave);line-height:1.45}
.p-chispa{display:flex;align-items:flex-end;gap:3px;height:34px}
.p-chispa i{flex:1;background:var(--acento-lavado);border-radius:2px 2px 0 0;min-height:2px}
.p-chispa i.hoy{background:var(--acento)}
.p-dato{display:flex;justify-content:space-between;gap:var(--e3);padding:8px 0;
  border-bottom:1px solid var(--linea-tenue);font-size:var(--t-chico)}
.p-dato:last-child{border-bottom:0}
.p-dato span{color:var(--fg-suave)}
.p-dato b{font-weight:500;font-variant-numeric:tabular-nums}
