1. Setup y tipografía

library(tidyverse)   # dplyr, ggplot2, tidyr, stringr, readr, forcats
library(lubridate)
library(readxl)
library(sf)
library(scales)
library(showtext)    # tipografías Google Fonts
library(ggrepel)     # etiquetas directas
library(patchwork)   # composición de paneles
# Tipografías tipo Economist: serif para títulos, sans para cuerpo/datos.
# Si no hay internet, ggplot cae al default y todo sigue funcionando.
try({
  font_add_google("IBM Plex Serif", "plex_serif")
  font_add_google("IBM Plex Sans",  "plex_sans")
  font_add_google("IBM Plex Mono",  "plex_mono")
  showtext_auto()
  showtext_opts(dpi = 150)
}, silent = TRUE)

# Alias seguros
f_serif <- "plex_serif"
f_sans  <- "plex_sans"
f_mono  <- "plex_mono"
# Paleta inspirada en The Economist
econ <- list(
  red        = "#E3120B",  # rojo Economist (acento crítico)
  navy       = "#14213D",  # azul profundo (contrapeso)
  teal       = "#006BA2",  # azul medio (series secundarias)
  gold       = "#EFB700",  # ocre (tercera serie si hace falta)
  gray_dark  = "#3F3F3F",
  gray_mid   = "#7A7A7A",
  gray_light = "#C9C6BE",
  cream      = "#FBF7EC",  # fondo del plot
  paper      = "#FFFFFF"   # fondo del panel externo
)

theme_econ <- function(base_size = 12) {
  theme_minimal(base_size = base_size, base_family = f_sans) +
    theme(
      plot.background     = element_rect(fill = econ$paper, color = NA),
      panel.background    = element_rect(fill = econ$cream, color = NA),
      panel.grid.major.y  = element_line(color = econ$gray_light, linewidth = 0.35),
      panel.grid.minor    = element_blank(),
      panel.grid.major.x  = element_blank(),
      plot.title          = element_text(family = f_serif, face = "bold",
                                         size = base_size + 5, color = econ$gray_dark,
                                         margin = margin(b = 4)),
      plot.subtitle       = element_text(family = f_sans, size = base_size,
                                         color = econ$gray_mid, margin = margin(b = 12)),
      plot.caption        = element_text(family = f_mono, size = base_size - 3,
                                         color = econ$gray_mid, hjust = 0,
                                         margin = margin(t = 12)),
      plot.caption.position = "plot",
      plot.title.position   = "plot",
      axis.title          = element_text(family = f_sans, size = base_size - 1,
                                         color = econ$gray_mid),
      axis.text           = element_text(family = f_sans, size = base_size - 2,
                                         color = econ$gray_dark),
      axis.ticks.x        = element_line(color = econ$gray_mid, linewidth = 0.3),
      axis.ticks.y        = element_blank(),
      strip.text          = element_text(family = f_serif, face = "bold",
                                         size = base_size, color = econ$gray_dark,
                                         hjust = 0),
      legend.position     = "top",
      legend.justification = "left",
      legend.title        = element_blank(),
      legend.text         = element_text(family = f_sans, size = base_size - 2,
                                         color = econ$gray_dark),
      legend.key.height   = unit(0.4, "cm"),
      plot.margin         = margin(18, 18, 12, 18)
    )
}

# Marca visual: barrita roja arriba a la izquierda del título (opcional)
econ_tag <- function(p) {
  p + labs(tag = "▎") +
    theme(plot.tag = element_text(color = econ$red, size = 22,
                                  family = f_serif, face = "bold"),
          plot.tag.position = c(0.005, 0.985))
}

caption_std <- "Fuente: SESNSP / RNID, corte a junio 2026.  |  @campameza"

2. Lectura y limpieza

ruta_rnid <- "/Volumes/ADATA Campa/Seguridad Institucional/RNID-Víctimas_Municipal-2026-jun2026.csv"

# El RNID viene en Mac Roman (huella de mojibake: "‡" = á, "Ž" = é, "'" = ').
# encoding = "macintosh" resuelve el problema en la fuente y evita parches str_replace.
RNID <- read_csv(ruta_rnid, locale = locale(encoding = "macintosh"))

# Fallback si el CSV realmente fuera Windows-1252 en otra máquina:
# RNID <- read_csv(ruta_rnid, locale = locale(encoding = "Windows-1252"))

# Normalizamos nombres de columnas por si vienen con caracteres raros residuales.
names(RNID) <- names(RNID) |>
  str_replace_all("A.o", "Año") |>
  str_replace_all("Bien jur.dico afectado", "Bien jurídico afectado")

meses_es <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
              "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")

meses_map <- setNames(
  c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"),
  meses_es
)
    # Detectamos qué meses realmente vienen en el archivo (jun 2026 → solo Ene-Jun)
meses_disponibles <- intersect(meses_es, names(RNID))

RNID_final <- RNID |>
  pivot_longer(cols = all_of(meses_disponibles),
               names_to = "Mes", values_to = "Total_Victimas") |>
  filter(!is.na(Total_Victimas)) |>
  mutate(
    Mes   = factor(Mes, levels = meses_es),
    Fecha = ymd(paste(Año, str_replace_all(as.character(Mes), meses_map), "01", sep = "-"))
  )
serie_hist <- read_csv("/Volumes/ADATA Campa/Seguridad Institucional/serie_hist_feminicidio_nl.csv") |>
  mutate(mes = as.Date(mes))
# Clasificador único de tipos de agresión — reusable en todas las tablas.
clasificar <- function(df) {
  df |>
    mutate(
      Tipo_Fem = case_when(
        str_detect(`Subtipo de delito`, "(?i)^Feminicidio") &
          !str_detect(Modalidad, "(?i)intento|tentativa") ~ "Feminicidio",
        str_detect(`Subtipo de delito`, "(?i)feminicidio") &
          str_detect(Modalidad, "(?i)intento|tentativa") ~ "Tentativa de feminicidio",
        TRUE ~ NA_character_
      ),
      Tipo_Muerte_Mujer = case_when(
        str_detect(`Subtipo de delito`, "(?i)^Feminicidio") &
          !str_detect(Modalidad, "(?i)intento|tentativa") ~ "Feminicidio",
        str_detect(`Subtipo de delito`, "(?i)Homicidio doloso") &
          !str_detect(Modalidad, "(?i)intento|tentativa") ~ "Homicidio doloso",
        TRUE ~ NA_character_
      ),
      Tipo_Agresion = case_when(
        str_detect(`Subtipo de delito`, "(?i)Lesiones dolosas") ~ "Lesiones dolosas",
        str_detect(`Subtipo de delito`, "(?i)feminicidio") &
          str_detect(Modalidad, "(?i)intento|tentativa") ~ "Tentativa de feminicidio",
        TRUE ~ NA_character_
      )
    )
}

RNID_clas <- clasificar(RNID_final)

3. Aportación de NL al total nacional

tabla_apilada <- RNID_clas |>
  filter(!is.na(Tipo_Fem)) |>
  mutate(Region = if_else(Clave_Ent == 19, "Nuevo León", "Resto del país")) |>
  group_by(Region, Mes, Tipo_Fem) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop") |>
  mutate(Region = factor(Region, levels = c("Resto del país", "Nuevo León")))

p1 <- ggplot(tabla_apilada, aes(x = Mes, y = Total, fill = Region)) +
  geom_col(position = "stack", width = 0.72) +
  facet_wrap(~Tipo_Fem, scales = "free_y") +
  scale_fill_manual(values = c("Resto del país" = econ$gray_light,
                               "Nuevo León"     = econ$red)) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.08))) +
  labs(
    title    = "Nuevo León concentra 1 de cada 3 tentativas nacionales",
    subtitle = "Víctimas mensuales de feminicidio consumado vs. tentativa | Enero–Junio 2026",
    x = NULL, y = "Víctimas",
    caption = caption_std
  ) +
  theme_econ() +
  theme(axis.text.x = element_text(angle = 0))

econ_tag(p1)

4. Top 10 municipios de NL en tentativas

top_mun_nl <- RNID_clas |>
  filter(Clave_Ent == 19, Tipo_Fem == "Tentativa de feminicidio") |>
  group_by(Municipio) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop") |>
  filter(Total > 0) |>
  slice_max(Total, n = 10)

p2 <- ggplot(top_mun_nl, aes(x = Total, y = fct_reorder(Municipio, Total))) +
  geom_col(fill = econ$navy, width = 0.7) +
  geom_text(aes(label = Total), hjust = -0.35, family = f_mono,
            size = 3.4, color = econ$gray_dark) +
  scale_x_continuous(expand = expansion(mult = c(0, 0.12))) +
  labs(
    title    = "El área metropolitana concentra las tentativas",
    subtitle = "Top 10 municipios de Nuevo León por víctimas | Enero–Junio 2026",
    x = "Víctimas", y = NULL,
    caption = caption_std
  ) +
  theme_econ() +
  theme(panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(color = econ$gray_light, linewidth = 0.35),
        axis.text.y = element_text(face = "bold", size = 10))

econ_tag(p2)

5. Frontera de tipificación: lesiones dolosas vs. tentativa

tabla_frontera <- RNID_clas |>
  filter(Clave_Ent == 19, Sexo == "Mujer", !is.na(Tipo_Agresion)) |>
  group_by(Mes, Tipo_Agresion) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop")

# Etiquetas al final de cada línea en lugar de leyenda
etiquetas_fin <- tabla_frontera |>
  filter(Mes == last(levels(Mes)[levels(Mes) %in% Mes]))

p3 <- ggplot(tabla_frontera, aes(x = Mes, y = Total,
                                  color = Tipo_Agresion, group = Tipo_Agresion)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 2.5) +
  geom_text_repel(data = etiquetas_fin, aes(label = Tipo_Agresion),
                  family = f_sans, fontface = "bold", size = 3.6,
                  hjust = 0, nudge_x = 0.3, direction = "y",
                  segment.color = NA, xlim = c(NA, Inf)) +
  scale_color_manual(values = c("Lesiones dolosas" = econ$gold,
                                "Tentativa de feminicidio" = econ$red)) +
  scale_x_discrete(expand = expansion(add = c(0.2, 2))) +
  labs(
    title    = "Dos etiquetas para el mismo universo de casos",
    subtitle = "Víctimas mensuales en NL bajo cada tipificación | Enero–Junio 2026",
    x = NULL, y = "Víctimas",
    caption = caption_std
  ) +
  theme_econ() +
  theme(legend.position = "none")

econ_tag(p3)

6. Feminicidio vs. homicidio doloso en NL

tabla_muertes <- RNID_clas |>
  filter(Clave_Ent == 19, Sexo == "Mujer", !is.na(Tipo_Muerte_Mujer)) |>
  group_by(Mes, Tipo_Muerte_Mujer) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop")

p4 <- ggplot(tabla_muertes, aes(x = Mes, y = Total, fill = Tipo_Muerte_Mujer)) +
  geom_col(position = position_dodge(width = 0.7), width = 0.62) +
  scale_fill_manual(values = c("Feminicidio" = econ$red,
                               "Homicidio doloso" = econ$navy)) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.08))) +
  labs(
    title    = "Por cada feminicidio, entre 3 y 5 homicidios dolosos de mujeres",
    subtitle = "Muertes violentas de mujeres en NL según tipificación | 2026",
    x = NULL, y = "Víctimas",
    caption = paste(caption_std,
                    "El diferencial sugiere subtipificación de casos que podrían cumplir razones de género.",
                    sep = "\n")
  ) +
  theme_econ()

econ_tag(p4)

7. Análisis nuevo: ratio tentativa / consumado por estado

Un intento de feminicidio, por definición, casi mata. Si un estado registra muchas tentativas y pocos consumados, o vive un milagro de servicios de urgencia, o está usando la categoría con criterios distintos al resto del país.

ratio_estatal <- RNID_clas |>
  filter(!is.na(Tipo_Fem)) |>
  group_by(Entidad, Clave_Ent, Tipo_Fem) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop") |>
  pivot_wider(names_from = Tipo_Fem, values_from = Total, values_fill = 0) |>
  mutate(
    Total_casos = Feminicidio + `Tentativa de feminicidio`,
    Ratio       = `Tentativa de feminicidio` / pmax(Feminicidio, 1),
    Es_NL       = Clave_Ent == 19
  ) |>
  filter(Total_casos >= 10) |>   # excluye estados con volumen mínimo (ruido)
  arrange(desc(Ratio))

p5 <- ggplot(ratio_estatal, aes(x = Ratio, y = fct_reorder(Entidad, Ratio),
                                 fill = Es_NL)) +
  geom_col(width = 0.72) +
  geom_text(aes(label = sprintf("%.1f×", Ratio)),
            hjust = -0.2, family = f_mono, size = 3, color = econ$gray_dark) +
  scale_fill_manual(values = c(`FALSE` = econ$gray_light, `TRUE` = econ$red),
                    guide = "none") +
  scale_x_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(
    title    = "Nuevo León: la ratio tentativa/consumado más alta del país",
    subtitle = "Tentativas de feminicidio por cada feminicidio consumado | Enero–Junio 2026",
    x = "Tentativas por cada consumado", y = NULL,
    caption = paste(caption_std,
                    "Se excluyen entidades con menos de 10 casos totales.",
                    sep = "\n")
  ) +
  theme_econ() +
  theme(panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(color = econ$gray_light, linewidth = 0.35),
        axis.text.y = element_text(size = 9))

econ_tag(p5)

8. Análisis nuevo: razón de tipificación por estado

La proporción feminicidios / (feminicidios + homicidios dolosos de mujeres) mide qué tanto una fiscalía usa la categoría feminicidio cuando muere violentamente una mujer. Los estados con proporciones muy bajas están, probablemente, absorbiendo casos en la categoría genérica.

razon_tipif <- RNID_clas |>
  filter(Sexo == "Mujer", !is.na(Tipo_Muerte_Mujer)) |>
  group_by(Entidad, Clave_Ent, Tipo_Muerte_Mujer) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop") |>
  pivot_wider(names_from = Tipo_Muerte_Mujer, values_from = Total, values_fill = 0) |>
  mutate(
    Muertes_totales = Feminicidio + `Homicidio doloso`,
    Prop_Fem        = Feminicidio / pmax(Muertes_totales, 1),
    Es_NL           = Clave_Ent == 19
  ) |>
  filter(Muertes_totales >= 10) |>
  arrange(Prop_Fem)

media_nacional <- weighted.mean(razon_tipif$Prop_Fem, razon_tipif$Muertes_totales)

p6 <- ggplot(razon_tipif, aes(x = Prop_Fem, y = fct_reorder(Entidad, Prop_Fem),
                               fill = Es_NL)) +
  geom_col(width = 0.72) +
  geom_vline(xintercept = media_nacional, color = econ$navy,
             linetype = "dashed", linewidth = 0.5) +
  annotate("text", x = media_nacional, y = 3,
           label = sprintf(" media nacional: %.0f%%", media_nacional * 100),
           family = f_mono, size = 3, color = econ$navy, hjust = 0) +
  scale_x_continuous(labels = percent_format(accuracy = 1),
                     expand = expansion(mult = c(0, 0.08))) +
  scale_fill_manual(values = c(`FALSE` = econ$gray_light, `TRUE` = econ$red),
                    guide = "none") +
  labs(
    title    = "¿Cuántas muertes violentas de mujeres se clasifican como feminicidio?",
    subtitle = "Feminicidios / (feminicidios + homicidios dolosos de mujeres) por entidad | 2026",
    x = "Proporción clasificada como feminicidio", y = NULL,
    caption = paste(caption_std,
                    "Una proporción baja no indica menos violencia, sino menos uso de la categoría.",
                    sep = "\n")
  ) +
  theme_econ() +
  theme(panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(color = econ$gray_light, linewidth = 0.35),
        axis.text.y = element_text(size = 9))

econ_tag(p6)

9. Mapa municipal: tasa y volumen

ruta_shp <- "/Users/christiancampa/Documents/Documents - MacBook Pro de Christian/Fosas/Mapa Federal con División Política/mun21cw.shp"

mapa_nl <- st_read(ruta_shp, quiet = TRUE) |>
  # El marco INEGI usa CVE_ENT / CVE_MUN por separado; los concatenamos a 5 dígitos
  mutate(
    CVEGEO = paste0(
      str_pad(CVE_ENT, 2, pad = "0"),
      str_pad(CVE_MUN, 3, pad = "0")
    )
  ) |>
  filter(CVE_ENT == "19") |>
  st_transform(crs = 6372)  # proyección oficial de INEGI para México, evita distorsión
# Suavizado bayesiano empírico simple para atenuar el small-numbers problem
# en municipios con población baja (evita que 1-2 casos en un municipio
# de 15k habitantes generen tasas engañosamente altas).
suavizar_eb <- function(x, n, k = 5) {
  tasa_global <- sum(x) / sum(n)
  (x + k * tasa_global * n / 1e5) / (n + k * n / 1e5) * 1e5
}

ruta_pob   <- "/Volumes/ADATA Campa/01_DATA_LIBRARY/Población_Mun_Projected.xlsx"

poblacion_nl <- read_excel(ruta_pob) |>
  filter(Año == 2026, `State ID` == 19) |>
  transmute(
    CVEGEO    = str_pad(as.character(`Municipality ID`), 5, pad = "0"),
    NOM_MUN,
    Poblacion = `Projected Population`
  )

tabla_mapa <- RNID_clas |>
  filter(Clave_Ent == 19, Tipo_Fem == "Tentativa de feminicidio") |>
  group_by(`Cve. Municipio`) |>
  summarise(Total = sum(Total_Victimas), .groups = "drop") |>
  mutate(CVEGEO = str_pad(as.character(`Cve. Municipio`), 5, pad = "0"))

tabla_tasas <- poblacion_nl |>
  left_join(tabla_mapa, by = "CVEGEO") |>
  mutate(
    Total    = replace_na(Total, 0),
    Tasa     = Total / Poblacion * 1e5,
    Tasa_EB  = suavizar_eb(Total, Poblacion)
  )

# NOTA: mapa_nl debe existir como sf en tu sesión. Si aún no lo cargas:
# mapa_nl <- st_read("ruta/al/shape_municipal_NL.shp") |>
#   mutate(CVEGEO = str_pad(CVEGEO, 5, pad = "0"))
mapa_unido <- mapa_nl |> left_join(tabla_tasas, by = "CVEGEO")

p7 <- ggplot(mapa_unido) +
  geom_sf(aes(fill = Tasa_EB), color = "white", linewidth = 0.25) +
  scale_fill_gradientn(
    colors = c(econ$cream, "#F4B183", econ$red, econ$navy),
    name   = "Tasa suavizada\npor 100k hab.",
    na.value = econ$gray_light
  ) +
  labs(
    title    = "Intensidad municipal, ajustada por población pequeña",
    subtitle = "Tasa suavizada (bayesiano empírico) de tentativa de feminicidio | Ene–Jun 2026",
    caption  = paste(caption_std,
                     "Suavizado atenúa municipios donde 1-2 casos generarían tasas engañosas.",
                     sep = "\n")
  ) +
  theme_econ() +
  theme(panel.background = element_rect(fill = econ$paper, color = NA),
        panel.grid = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank())

econ_tag(p7)

p8 <- ggplot(mapa_unido) +
  geom_sf(aes(fill = Total), color = "white", linewidth = 0.25) +
  scale_fill_gradientn(
    colors = c(econ$cream, "#F4B183", econ$red, econ$navy),
    name   = "Víctimas",
    na.value = econ$gray_light
  ) +
  labs(
    title    = "Volumen absoluto: la carga se concentra en el área metropolitana",
    subtitle = "Tentativas de feminicidio | Ene–Jun 2026",
    caption  = caption_std
  ) +
  theme_econ() +
  theme(panel.background = element_rect(fill = econ$paper, color = NA),
        panel.grid = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank())

econ_tag(p8)

# ============================================================
# 11. Serie histórica 2015-2026: NL vs promedio nacional
# ============================================================

ruta_hist <- "/Volumes/ADATA Campa/Seguridad Institucional/serie_hist_feminicidio_nl.csv"  # ajústala

serie_hist <- read_csv(ruta_hist) |>
  mutate(mes = as.Date(mes))

# 2026 desde el RNID que ya tenemos en memoria
serie_2026_nl <- RNID_clas |>
  filter(Clave_Ent == 19, Tipo_Fem == "Feminicidio") |>
  group_by(mes = Fecha) |>
  summarise(nl_total = sum(Total_Victimas), .groups = "drop")

serie_2026_prom <- RNID_clas |>
  filter(Tipo_Fem == "Feminicidio") |>
  group_by(Clave_Ent, mes = Fecha) |>
  summarise(total = sum(Total_Victimas), .groups = "drop") |>
  group_by(mes) |>
  summarise(prom_nacional = mean(total), .groups = "drop")

serie_2026 <- serie_2026_nl |> left_join(serie_2026_prom, by = "mes")

serie_completa <- bind_rows(serie_hist, serie_2026) |>
  pivot_longer(c(nl_total, prom_nacional),
               names_to = "serie", values_to = "valor") |>
  mutate(serie = recode(serie,
                        nl_total     = "Nuevo León",
                        prom_nacional = "Promedio nacional por entidad"))

corte_2026 <- as.Date("2026-01-01")

etiquetas_serie <- serie_completa |>
  filter(mes == max(mes)) |>
  arrange(desc(valor))

p9 <- ggplot(serie_completa, aes(x = mes, y = valor, color = serie)) +
  annotate("rect", xmin = corte_2026, xmax = max(serie_completa$mes),
           ymin = -Inf, ymax = Inf, fill = econ$gray_light, alpha = 0.35) +
  annotate("text", x = corte_2026, y = Inf,
           label = "  Nueva metodología →", hjust = 0, vjust = 1.6,
           family = f_mono, size = 3, color = econ$gray_dark) +
  geom_vline(xintercept = corte_2026, color = econ$gray_dark,
             linetype = "dashed", linewidth = 0.4) +
  geom_line(linewidth = 0.9) +
  geom_text_repel(data = etiquetas_serie, aes(label = serie),
                  family = f_sans, fontface = "bold", size = 3.4,
                  hjust = 0, nudge_x = 60, direction = "y",
                  segment.color = NA, xlim = c(NA, Inf)) +
  scale_color_manual(values = c("Nuevo León" = econ$red,
                                "Promedio nacional por entidad" = econ$navy),
                     guide = "none") +
  scale_x_date(date_breaks = "1 year", date_labels = "%Y",
               expand = expansion(mult = c(0.01, 0.12))) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.08))) +
  labs(
    title    = "La caída de NL antecede al cambio metodológico",
    subtitle = "Feminicidios consumados mensuales | 2015–2026",
    x = NULL, y = "Feminicidios consumados",
    caption = paste(caption_std,
                    "El sombreado marca la vigencia de la nueva tipología SESNSP.",
                    sep = "\n")
  ) +
  theme_econ()

econ_tag(p9)

10. Resumen

Los indicadores apuntan de forma convergente a un cambio de tipificación más que a un cambio en el fenómeno subyacente:

  • NL es outlier extremo en la ratio tentativa / consumado.
  • NL registra proporciones bajas en la razón feminicidio / muertes violentas de mujeres.
  • Las series de lesiones dolosas y tentativa se mueven en paralelo, sugiriendo una frontera de clasificación porosa.
  • La caída histórica de feminicidios consumados en NL 2024→2025 no tiene contrapartida en la serie de muertes violentas totales.

La hipótesis a probar es que el requerimiento metodológico 2026 del SESNSP está forzando a la Fiscalía de NL a reportar tentativas que antes se absorbían en categorías genéricas, sin que el ajuste hacia arriba (homicidio → feminicidio consumado) haya ocurrido con la misma disciplina.