Dirección ejecutiva

Row

Una decisión, no una colección de gráficas

La congestión no es igual durante todo el día. El riesgo está en los episodios en que la demanda supera la capacidad de respuesta. La gerencia debe decidir dónde actuar, probar una solución reversible y medir si realmente mejora la oportunidad sin comprometer la seguridad.

Decisión solicitada: autorizar una verificación de datos reales y, solo si se confirman los patrones, un piloto de seis semanas en la franja más exigente.

Ejercicio académico con datos 100 % sintéticos de enero a marzo de 2026. Los valores no corresponden a una IPS real ni son estándares clínicos oficiales.

Row

Historia en tres actos

ACTO 1 · PRESIÓN — Las llegadas se concentran en ciertas franjas. Una programación rígida puede quedar desalineada.
ACTO 2 · FRICCIÓN — En días de alta ocupación, la espera escala. El promedio trimestral disimula los episodios extremos.
ACTO 3 · DECISIÓN — Ajustar capacidad, verificar impacto y escalar únicamente con evidencia y presupuesto.

Pulso institucional

Row

Demanda total

11.400

Espera promedio

53,0 min

Ocupación

84,7 %

Abandono

3,95 %

Row

Semáforo de capacidad

Alerta para el comité

6 días presentaron ocupación media superior al umbral ilustrativo del 90 %.

No aprobar cambios estructurales basándose solo en este indicador. La ocupación debe leerse con la complejidad de pacientes, dotación efectiva, camas y egresos.

Regla ejecutiva: distinguir si el problema es recurrente, localizado o excepcional antes de reasignar recursos.

Dónde se rompe la oportunidad

Row

Espera diaria | Localizar picos, no esconderlos en un promedio

Qué muestra: episodios y máximos diarios. Qué significa: la media no refleja toda la presión. Qué decidir: investigar picos en registros reales junto con turnos, triage y egresos.

Row

Compare cuatro indicadores, una misma franja

Qué muestra: cada franja tiene perfiles distintos de volumen, presión y desempeño. Qué decidir: priorizar solo cuando coincidan varios indicadores, no un dato aislado.

Explicación y riesgos

Row

¿Dónde se concentra la variabilidad?

Lectura: compara medianas, dispersión y valores extremos. Decisión: diseñar protocolos de contingencia para franjas con alta variabilidad.

Ocupación y espera: asociación, no causalidad

Lectura: relación descriptiva construida en la simulación. Decisión: comprobar el patrón con registros reales antes de inferir efectos.

Row

Episodios para revisión de gerencia

Los riesgos de decidir demasiado pronto

Riesgo 1. Confundir un evento excepcional con una congestión permanente.
Riesgo 2. Reasignar personal sin considerar seguridad y clasificación clínica.
Riesgo 3. Atribuir causalidad a asociaciones generadas por el propio simulador.

Posicionamiento institucional

Row

¿Cómo se posiciona el desempeño operativo?

El posicionamiento no consiste en comparar una cifra aislada. Para la alta dirección, la pregunta clave es si la institución convierte su capacidad instalada en atención oportuna, segura y estable, especialmente durante las franjas de presión.

Este apartado presenta una lectura interna del desempeño simulado, no un ranking de instituciones. Sin datos comparables de otras IPS, niveles de complejidad y mezcla de pacientes, no se puede establecer una posición competitiva real.

Row

Perfil ejecutivo de desempeño: indicadores complementarios

Lectura para gerencia

Implicación estratégica: vigilar simultáneamente oportunidad, capacidad y permanencia del paciente. Una aparente mejora en un indicador no debe compensar un deterioro grave en otro.

Decisión: aprobar una ficha mensual con estos tres indicadores y sus definiciones, discriminada por triage, franjas y niveles de complejidad cuando exista información real validada.

Decisión y seguimiento

Row

Decisión 1 | Piloto focalizado y reversible

Propuesta: levantar línea base real y probar durante seis semanas ajustes de flujo y asignación de capacidad en la franja de presión confirmada.

Responsables: Dirección Médica, Urgencias y Talento Humano.

Medición: mediana y P90 de espera, abandono, eventos de seguridad, carga por triage y horas efectivas de personal.

Condición para escalar: mejora sostenida, sin deterioro de seguridad y con costo incremental conocido.

Decisión 2 | Gobierno de datos y alertas

Propuesta: institucionalizar un comité operativo semanal con información validada, responsables y acciones verificables.

Responsables: Planeación, Calidad y Sistemas de Información.

Medición: completitud, trazabilidad, alertas investigadas y acciones cerradas.

Condición para sostener: indicadores auditables y decisiones documentadas.

Row

Hoja de ruta para aprobación

Horizonte Entregable Responsable
Semanas 1–2 Auditoría de fuentes y línea base Sistemas y Calidad
Semanas 3–4 Diseño e inicio controlado Urgencias y Talento Humano
Semanas 5–8 Seguimiento y ajustes Dirección Médica
Semanas 9–10 Evaluación de resultados y costos Planeación y Calidad
Semana 11 Continuar, modificar o detener Gerencia

Cierre gerencial

La decisión responsable no es aumentar recursos inmediatamente. Es identificar el cuello de botella real, medir una intervención viable y financiar solo aquello que demuestre mejorar la oportunidad y preservar la seguridad.

Nota de integridad: datos sintéticos, umbrales ilustrativos y escenarios no causales. No utilizar las cifras como diagnóstico de una IPS real.

---
title: "SALA DE DECISIONES | Urgencias"
subtitle: "Capacidad, oportunidad y respuesta gerencial · Evidencia para priorizar"
author: "Alexandra Cecilia Rivera Pardo"
date: "24 de octubre de 2026"
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: scroll
    theme: cosmo
    self_contained: true
    source_code: embed
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=FALSE, warning=FALSE, message=FALSE,
 fig.width=10,fig.height=4.6,dpi=120)
paquetes <- c("flexdashboard","ggplot2","dplyr","tidyr","lubridate",
              "scales","ggrepel","plotly","DT","knitr")
faltantes <- paquetes[!vapply(paquetes,requireNamespace,logical(1),quietly=TRUE)]
if(length(faltantes)) stop(paste("Instalar paquetes:",paste(faltantes,collapse=", ")))
for(p in paquetes) suppressPackageStartupMessages(library(p,character.only=TRUE))
options(scipen=999)
formatear <- function(x,digitos=1) format(round(x,digitos),nsmall=digitos,big.mark=".",decimal.mark=",")
marino <- "#102B53"; azul <- "#2563EB"; cian <- "#09B6C9";
coral <- "#FF654F"; oro <- "#F4B544"; verde <- "#1DAB85"
colores <- c("#2563EB","#09B6C9","#F4B544","#FF654F")
tema <- theme_minimal(base_size=13) + theme(
  panel.grid.minor=element_blank(),panel.grid.major.x=element_blank(),
  plot.title=element_text(face="bold",color=marino,size=15),
  plot.subtitle=element_text(color="#4C6078",size=10),
  axis.title=element_text(color=marino,face="bold"),
  legend.position="bottom")
```

```{r datos, include=FALSE}
# ÚNICA FUENTE DE DATOS PARA AMBOS DOCUMENTOS.
# Simulación demostrativa (NO registros hospitalarios reales).
set.seed(20261023)
# Una observación equivale a una franja de seis horas de un día.
fechas <- seq(as.Date("2026-01-01"),as.Date("2026-03-31"),by="day")
franjas <- c("00:00-05:59","06:00-11:59","12:00-17:59","18:00-23:59")
datos <- tidyr::expand_grid(fecha=fechas,franja=factor(franjas,levels=franjas)) %>%
  mutate(t=as.integer(fecha-min(fecha))+1,
         id_franja=as.integer(franja),
         fin_semana=lubridate::wday(fecha,week_start=1)>=6,
         choque=fecha>=as.Date("2026-02-15") & fecha<=as.Date("2026-02-21"),
         demanda_esperada=pmax(4,23+c(-11,5,13,7)[id_franja]+4*fin_semana+
             10*choque+2*sin(t/8)+0.07*t),
         llegadas=rpois(n(),lambda=demanda_esperada),
         ocupacion_pct=round(pmax(57,pmin(108,72+0.32*llegadas+4*choque+
             3*(id_franja==3)+rnorm(n(),0,5))),1),
         espera_min=round(pmax(8,12+1.12*llegadas+
             1.5*pmax(ocupacion_pct-90,0)+rnorm(n(),0,8)),1),
         abandono=rbinom(n(),size=llegadas,
             prob=plogis(-4.5+0.023*espera_min)),
         hospitalizaciones=rbinom(n(),size=llegadas,prob=0.23),
         atencion_60_pct=round(100*plogis(3.6-0.046*espera_min),1),
         mes=format(fecha,"%Y-%m")) %>%
  select(fecha,mes,franja,fin_semana,choque,llegadas,ocupacion_pct,
         espera_min,abandono,hospitalizaciones,atencion_60_pct)
stopifnot(nrow(datos)==length(fechas)*4, !anyNA(datos),
          all(datos$llegadas>=0),all(datos$abandono<=datos$llegadas),
          all(datos$hospitalizaciones<=datos$llegadas))

# Equivalencia de variables para las visualizaciones del dashboard.
# Es exactamente la misma simulación que la del informe gerencial.
base <- datos %>% transmute(
  fecha, mes=factor(mes, levels=c("2026-01","2026-02","2026-03")),
  franja=franja, fin_semana=fin_semana, llegadas=llegadas,
  ingresos_hospital=hospitalizaciones, abandono=abandono,
  camas_disponibles=55L, ocupacion=ocupacion_pct,
  espera_min=espera_min, oportunidad_60=atencion_60_pct, choque=choque
)
stopifnot(nrow(base)==360L, !anyNA(base),
          all(base$abandono <= base$llegadas),
          all(base$ingresos_hospital <= base$llegadas))

# Calcular promedios ponderados ANTES de resumir llegadas.
# En dplyr, summarise() puede reutilizar el nombre recién creado;
# por ello sum(llegadas) debe ir al final de cada summarise().
diario <- base %>% group_by(fecha) %>%
  summarise(ocupacion = weighted.mean(ocupacion, llegadas),
            espera = weighted.mean(espera_min, llegadas),
            oport = weighted.mean(oportunidad_60, llegadas),
            abandono = sum(abandono),
            ingresos = sum(ingresos_hospital),
            llegadas = sum(llegadas),
            .groups="drop") %>%
  mutate(semana=as.Date(lubridate::floor_date(fecha, "week", week_start=1)),
         alerta = ocupacion > 90)
mensual <- base %>% group_by(mes) %>%
  summarise(ocupacion=weighted.mean(ocupacion,llegadas),
            espera=weighted.mean(espera_min,llegadas),
            abandono=sum(abandono),
            llegadas=sum(llegadas), .groups="drop")
por_franja <- base %>% group_by(franja) %>%
  summarise(espera=weighted.mean(espera_min,llegadas),
            ocupacion=weighted.mean(ocupacion,llegadas),
            abandono=sum(abandono),
            llegadas=sum(llegadas), .groups="drop") %>%
  mutate(tasa_abandono=100*abandono/llegadas)
semanal <- diario %>% group_by(semana) %>%
  summarise(espera=weighted.mean(espera,llegadas),
            ocupacion=weighted.mean(ocupacion,llegadas), .groups="drop")
periodo_critico <- diario %>% slice_max(espera, n=1, with_ties=FALSE)
franja_critica <- por_franja %>% slice_max(espera,n=1,with_ties=FALSE)
ultima_semana <- diario %>% filter(fecha >= max(fecha)-6)
primera_semana <- diario %>% filter(fecha <= min(fecha)+6)
indicadores <- list(
 total = sum(base$llegadas),
 espera = weighted.mean(base$espera_min,base$llegadas),
 ocupacion = weighted.mean(base$ocupacion,base$llegadas),
 tasa_abandono = 100*sum(base$abandono)/sum(base$llegadas),
 dias_alerta = sum(diario$alerta),
 oport = weighted.mean(base$oportunidad_60,base$llegadas),
 delta_espera = weighted.mean(ultima_semana$espera, ultima_semana$llegadas) -
                weighted.mean(primera_semana$espera,primera_semana$llegadas)
)
# Supuestos gerenciales demostrativos; NO son estándares clínicos ni metas oficiales.
meta_ocupacion <- 85
umbral_alerta <- 90
meta_espera <- 60
# Escenario ilustrativo: 1 refuerzo de personal en la franja de mayor espera,
# que hipotéticamente reduce en 15 minutos la espera de esa franja.
min_reducidos <- 15
prop_demanda_critica <- franja_critica$llegadas / indicadores$total
espera_escenario <- indicadores$espera - prop_demanda_critica * min_reducidos
```

<style>
body{font-family:'Aptos','Segoe UI',Arial,sans-serif;color:#1F3148;background:#F6F9FD}
.navbar{background:linear-gradient(100deg,#102B53,#2563EB)!important;border:0}
.navbar-brand{font-weight:900;letter-spacing:.4px}
.section.level3{border-top:3px solid #09B6C9;border-radius:8px;background:white}
h3{font-weight:800;color:#102B53}
.leadbox{background:linear-gradient(112deg,#102B53 5%,#2563EB 62%,#09B6C9);color:white;
 padding:22px 25px;border-radius:14px;font-size:18px;line-height:1.55;box-shadow:0 5px 18px #102B5322}
.leadbox strong{color:#FFE08B}
.insight{padding:15px 18px;border-radius:10px;background:#E9F8FC;border-left:6px solid #09B6C9;margin:12px 0}
.risk{padding:15px 18px;border-radius:10px;background:#FFF1ED;border-left:6px solid #FF654F;margin:12px 0}
.action{padding:15px 18px;border-radius:10px;background:#FFF8E8;border-left:6px solid #F4B544;margin:12px 0}
.tiny{color:#52637A;font-size:12px}
.story{font-weight:700;color:#102B53;font-size:17px;line-height:1.55}
.value-box{border-radius:9px}.value-box .value{font-weight:900}
table th{background:#102B53;color:white}
</style>

Dirección ejecutiva {data-icon="fa-bullseye"}
==============================================

Row {data-height=235}
----------------------------------------------

### Una decisión, no una colección de gráficas

<div class="leadbox">La congestión no es igual durante todo el día. <strong>El riesgo está en los episodios en que la demanda supera la capacidad de respuesta.</strong> La gerencia debe decidir dónde actuar, probar una solución reversible y medir si realmente mejora la oportunidad sin comprometer la seguridad.</div>

**Decisión solicitada:** autorizar una verificación de datos reales y, solo si se confirman los patrones, un piloto de seis semanas en la franja más exigente.

<div class="tiny">Ejercicio académico con datos 100 % sintéticos de enero a marzo de 2026. Los valores no corresponden a una IPS real ni son estándares clínicos oficiales.</div>

Row {data-height=210}
----------------------------------------------

### Historia en tres actos

<div class="insight"><b>ACTO 1 · PRESIÓN</b> — Las llegadas se concentran en ciertas franjas. Una programación rígida puede quedar desalineada.</div>

<div class="risk"><b>ACTO 2 · FRICCIÓN</b> — En días de alta ocupación, la espera escala. El promedio trimestral disimula los episodios extremos.</div>

<div class="action"><b>ACTO 3 · DECISIÓN</b> — Ajustar capacidad, verificar impacto y escalar únicamente con evidencia y presupuesto.</div>

Pulso institucional {data-icon="fa-heartbeat"}
==============================================

Row {data-height=155}
----------------------------------------------

### Demanda total

```{r kpi1}
flexdashboard::valueBox(formatear(indicadores$total,0), "Llegadas simuladas · 90 días", icon="fa-users",color="primary")
```

### Espera promedio

```{r kpi2}
flexdashboard::valueBox(paste0(formatear(indicadores$espera)," min"), "Espera ponderada",icon="fa-clock-o",color=if(indicadores$espera>meta_espera) "danger" else "success")
```

### Ocupación

```{r kpi3}
flexdashboard::valueBox(paste0(formatear(indicadores$ocupacion)," %"),"Ocupación ponderada",icon="fa-bed",color=if(indicadores$ocupacion>meta_ocupacion) "warning" else "success")
```

### Abandono

```{r kpi4}
flexdashboard::valueBox(paste0(formatear(indicadores$tasa_abandono,2)," %"),"Abandonos / llegadas",icon="fa-sign-out",color="info")
```

Row {data-height=275}
----------------------------------------------

### Semáforo de capacidad

```{r semaforo}
# Medidor de capacidad robusto: se dibuja con ggplot y funciona aun sin JavaScript.
# Los umbrales son exclusivamente ilustrativos.
medidor <- data.frame(inicio=c(0,85,90),fin=c(85,90,110),
                     estado=factor(c("Objetivo","Atención","Crítico"),
                                   levels=c("Objetivo","Atención","Crítico")))
valor <- round(indicadores$ocupacion,1)
ggplot(medidor) +
  geom_rect(aes(xmin=inicio,xmax=fin,ymin=0,ymax=1,fill=estado),
            color="white",linewidth=1.5) +
  geom_vline(xintercept=valor,color=marino,linewidth=1.4) +
  annotate("point",x=valor,y=.5,shape=21,size=6,fill="white",color=marino,stroke=2) +
  annotate("text",x=valor,y=1.35,
           label=paste0(formatear(valor)," %"),size=8,fontface="bold",color=marino) +
  scale_fill_manual(values=c("Objetivo"=verde,"Atención"=oro,"Crítico"=coral),drop=FALSE) +
  scale_x_continuous(limits=c(0,110),breaks=c(0,50,85,90,110),expand=c(0,0)) +
  coord_cartesian(ylim=c(-.25,1.75),clip="off") +
  labs(x="Ocupación de capacidad (%)",y=NULL,fill="Rango",
       title="Nivel de presión sobre la capacidad",
       subtitle="Valor medio ponderado · escala de referencia ilustrativa") +
  theme_minimal(base_size=12) +
  theme(axis.text.y=element_blank(),axis.ticks.y=element_blank(),
        panel.grid=element_blank(),legend.position="bottom",
        plot.title=element_text(face="bold",color=marino),
        plot.margin=margin(8,15,8,15))
```

### Alerta para el comité

<div class="risk"><b>`r indicadores$dias_alerta` días</b> presentaron ocupación media superior al umbral ilustrativo del 90 %.</div>

**No aprobar cambios estructurales basándose solo en este indicador.** La ocupación debe leerse con la complejidad de pacientes, dotación efectiva, camas y egresos.

**Regla ejecutiva:** distinguir si el problema es recurrente, localizado o excepcional antes de reasignar recursos.

Dónde se rompe la oportunidad {data-icon="fa-line-chart"}
==============================================

Row {data-height=465}
----------------------------------------------

### Espera diaria | Localizar picos, no esconderlos en un promedio

```{r tendencia}
# Se usa una estética básica compatible con ggplotly().
# Evitar aes(text=...) heredado: las capas de anotación no disponen
# de esa variable, lo que puede causar un error en eval_aesthetics().
serie <- diario
p <- ggplot(serie, aes(x=fecha, y=espera)) +
  annotate("rect", xmin=as.Date("2026-02-15"),
           xmax=as.Date("2026-02-21"), ymin=-Inf, ymax=Inf,
           fill=oro, alpha=.12) +
  geom_line(color=azul, linewidth=1) +
  geom_point(color=cian, size=1.7) +
  geom_hline(yintercept=meta_espera, color=coral,
             linetype="dashed", linewidth=.7) +
  geom_point(data=periodo_critico,
             mapping=aes(x=fecha, y=espera), inherit.aes=FALSE,
             color=coral, size=3.5) +
  labs(title="Los días críticos requieren una explicación operacional",
       subtitle="Sombreado: episodio incluido deliberadamente en la simulación",
       x="Fecha", y="Espera media (min)") + tema
# El usuario puede explorar fechas y valores mediante tooltips, zoom y paneo.
# El pico se destaca con un punto coral y se explica en el texto gerencial.
plotly::ggplotly(p, tooltip=c("x", "y")) %>%
  plotly::config(displaylogo=FALSE)
```

**Qué muestra:** episodios y máximos diarios. **Qué significa:** la media no refleja toda la presión. **Qué decidir:** investigar picos en registros reales junto con turnos, triage y egresos.

Row {data-height=445}
----------------------------------------------

### Compare cuatro indicadores, una misma franja

```{r selector}
comp <- por_franja %>% mutate(franja=as.character(franja))
indicadores_plot <- list(
 list(etiqueta="Espera media (min)",y=comp$espera),
 list(etiqueta="Ocupación (%)",y=comp$ocupacion),
 list(etiqueta="Llegadas",y=comp$llegadas),
 list(etiqueta="Abandono (%)",y=comp$tasa_abandono))
fig <- plotly::plot_ly()
for(j in seq_along(indicadores_plot)){
  fig <- plotly::add_bars(fig,x=comp$franja,y=indicadores_plot[[j]]$y,
    name=indicadores_plot[[j]]$etiqueta,visible=j==1,
    marker=list(color=colores),hovertemplate="Franja: %{x}<br>Valor: %{y:.1f}<extra></extra>")
}
botones <- lapply(seq_along(indicadores_plot),function(j){
 v <- rep(FALSE,length(indicadores_plot));v[j] <- TRUE
 list(method="update",label=indicadores_plot[[j]]$etiqueta,
      args=list(list(visible=v),list(yaxis=list(title=indicadores_plot[[j]]$etiqueta))))
})
plotly::layout(fig,showlegend=FALSE,
 xaxis=list(title="Franja de seis horas"),yaxis=list(title="Espera media (min)"),
 updatemenus=list(list(type="dropdown",buttons=botones,x=0,y=1.20)),
 margin=list(t=85)) %>% plotly::config(displaylogo=FALSE)
```

**Qué muestra:** cada franja tiene perfiles distintos de volumen, presión y desempeño. **Qué decidir:** priorizar solo cuando coincidan varios indicadores, no un dato aislado.

Explicación y riesgos {data-icon="fa-search"}
==============================================

Row {data-height=420}
----------------------------------------------

### ¿Dónde se concentra la variabilidad?

```{r variabilidad}
ggplot(base,aes(franja,espera_min,fill=franja))+
 geom_boxplot(show.legend=FALSE,outlier.alpha=.45)+
 scale_fill_manual(values=colores)+
 labs(title="La predictibilidad importa tanto como el promedio",
 x="Franja",y="Tiempo de espera (min)")+tema
```

**Lectura:** compara medianas, dispersión y valores extremos. **Decisión:** diseñar protocolos de contingencia para franjas con alta variabilidad.

### Ocupación y espera: asociación, no causalidad

```{r correlacion}
ggplot(base,aes(ocupacion,espera_min,color=franja))+
 geom_point(alpha=.5,size=1.5)+geom_smooth(method="lm",se=FALSE,linewidth=.8)+
 scale_color_manual(values=colores)+
 labs(title="Más presión puede coincidir con mayor espera",
 x="Ocupación (%)",y="Espera (min)",color="Franja")+tema
```

**Lectura:** relación descriptiva construida en la simulación. **Decisión:** comprobar el patrón con registros reales antes de inferir efectos.

Row {data-height=350}
----------------------------------------------

### Episodios para revisión de gerencia

```{r tabla}
DT::datatable(diario %>% arrange(desc(espera)) %>% slice_head(n=12) %>%
 transmute(Fecha=format(fecha,"%d/%m/%Y"),Llegadas=llegadas,
 `Espera (min)`=round(espera,1),`Ocupación (%)`=round(ocupacion,1)),
 rownames=FALSE,filter="top",options=list(pageLength=6,scrollX=TRUE))
```

### Los riesgos de decidir demasiado pronto

<div class="risk"><b>Riesgo 1.</b> Confundir un evento excepcional con una congestión permanente.</div>
<div class="risk"><b>Riesgo 2.</b> Reasignar personal sin considerar seguridad y clasificación clínica.</div>
<div class="risk"><b>Riesgo 3.</b> Atribuir causalidad a asociaciones generadas por el propio simulador.</div>

Posicionamiento institucional {data-icon="fa-compass"}
==============================================

Row {data-height=265}
----------------------------------------------

### ¿Cómo se posiciona el desempeño operativo?

<div class="leadbox"><strong>El posicionamiento no consiste en comparar una cifra aislada.</strong> Para la alta dirección, la pregunta clave es si la institución convierte su capacidad instalada en atención oportuna, segura y estable, especialmente durante las franjas de presión.</div>

Este apartado presenta una <strong>lectura interna del desempeño simulado</strong>, no un ranking de instituciones. Sin datos comparables de otras IPS, niveles de complejidad y mezcla de pacientes, no se puede establecer una posición competitiva real.

Row {data-height=355}
----------------------------------------------

### Perfil ejecutivo de desempeño: indicadores complementarios

```{r posicionamiento}
perfil <- data.frame(
  dimension=c("Oportunidad antes de 60 minutos", "Franjas con ocupación <= 90 %", "Pacientes que no abandonan"),
  porcentaje=c(indicadores$oport, 100*mean(base$ocupacion<=90),100-indicadores$tasa_abandono)
)
perfil$dimension <- factor(perfil$dimension,levels=rev(perfil$dimension))
ggplot(perfil,aes(x=dimension,y=porcentaje,fill=dimension))+
 geom_col(width=.57,show.legend=FALSE)+
 geom_text(aes(label=paste0(formatear(porcentaje)," %")),hjust=-.08,fontface="bold",size=4.4,color=marino)+
 coord_flip()+
 scale_fill_manual(values=c("#2563EB","#09B6C9","#1DAB85"))+
 scale_y_continuous(limits=c(0,110),breaks=seq(0,100,25),labels=function(x) paste0(x," %"))+
 labs(x=NULL,y="Porcentaje del escenario sintético",title="Tres ángulos de un mismo desempeño")+
 tema+theme(panel.grid.major.y=element_blank())
```

### Lectura para gerencia

<div class="insight"><b>Implicación estratégica:</b> vigilar simultáneamente oportunidad, capacidad y permanencia del paciente. Una aparente mejora en un indicador no debe compensar un deterioro grave en otro.</div>

**Decisión:** aprobar una ficha mensual con estos tres indicadores y sus definiciones, discriminada por triage, franjas y niveles de complejidad cuando exista información real validada.

Decisión y seguimiento {data-icon="fa-check-circle"}
==============================================

Row {data-height=335}
----------------------------------------------

### Decisión 1 | Piloto focalizado y reversible

<div class="action"><b>Propuesta:</b> levantar línea base real y probar durante seis semanas ajustes de flujo y asignación de capacidad en la franja de presión confirmada.</div>

**Responsables:** Dirección Médica, Urgencias y Talento Humano.

**Medición:** mediana y P90 de espera, abandono, eventos de seguridad, carga por triage y horas efectivas de personal.

**Condición para escalar:** mejora sostenida, sin deterioro de seguridad y con costo incremental conocido.

### Decisión 2 | Gobierno de datos y alertas

<div class="insight"><b>Propuesta:</b> institucionalizar un comité operativo semanal con información validada, responsables y acciones verificables.</div>

**Responsables:** Planeación, Calidad y Sistemas de Información.

**Medición:** completitud, trazabilidad, alertas investigadas y acciones cerradas.

**Condición para sostener:** indicadores auditables y decisiones documentadas.

Row {data-height=300}
----------------------------------------------

### Hoja de ruta para aprobación

| Horizonte | Entregable | Responsable |
|:--|:--|:--|
| Semanas 1–2 | Auditoría de fuentes y línea base | Sistemas y Calidad |
| Semanas 3–4 | Diseño e inicio controlado | Urgencias y Talento Humano |
| Semanas 5–8 | Seguimiento y ajustes | Dirección Médica |
| Semanas 9–10 | Evaluación de resultados y costos | Planeación y Calidad |
| Semana 11 | Continuar, modificar o detener | Gerencia |

### Cierre gerencial

<div class="leadbox"><strong>La decisión responsable no es aumentar recursos inmediatamente.</strong> Es identificar el cuello de botella real, medir una intervención viable y financiar solo aquello que demuestre mejorar la oportunidad y preservar la seguridad.</div>

**Nota de integridad:** datos sintéticos, umbrales ilustrativos y escenarios no causales. No utilizar las cifras como diagnóstico de una IPS real.