/* ============================================================================
   Juicy — Dashboard Design System · SIDEBAR
   ----------------------------------------------------------------------------
   Figma: "General UI" (1:3838) → Sidebar Menu Section (1:3966): la barra
   colapsada y la expandida, + Menu Sidebar Item con sus estados.

   AQUÍ NO SE REDISEÑÓ NADA (decisión del dueño, 2026-07-17): la barra YA era el
   Figma — su fondo y su ítem activo salen del preset de marca, que es lo que la
   sección pide ("MENU SIDEBAR (USES BRAND COLOR)"). Esta fase hizo dos cosas:
   la separó de main.css y la TOKENIZÓ. Lo que se ve es idéntico, verificado por
   foto en los 5 estados (colapsado, hover, ≥1920, táctil abierto y cerrado).

   Markup (templates/template-parts/dashboard_menu.php — PHP a mano, foreach
   sobre getDashboardMenu(); NO usa wp_nav_menu):

     <aside id="dashboard_sidebar">
       <div id="dashboard_logo"><a></a></div>
       <div id="dashboard_menu_wrapper">
         <ul id="dashboard_menu">
           <li>
             <div class="menu_item_wrapper">
               <a class="menu-link menu-item fi fi-rr-… current-menu-item"><span>Texto</span></a>
               <i class="submenu_trigger fi fi-rr-angle-small-down"></i>
             </div>
             <div class="submenu_wrapper"><ul class="sub-menu">…</ul></div>
           </li>
         </ul>
       </div>
       <div id="dashboard_sidebar_footer">…</div>
     </aside>

   El icono del ítem NO es un elemento aparte: las clases `fi fi-rr-…` van en el
   MISMO <a> que `.menu-link`, y el glifo lo pinta su `::before`. Ver nota 3.

   ⚠️ LOS NOMBRES SON DE WORDPRESS Y NO SE TOCAN. `.menu-item`, `.sub-menu`,
   `.menu-link` y `.current-menu-item` son las que genera `wp_nav_menu()`. Este
   markup solo las IMITA. En main.css estas reglas eran GLOBALES —sin acotar a la
   barra—, así que cualquier menú de WordPress del sitio recibía `height:60px` y
   compañía de un CSS pensado para el dashboard. Aquí quedan ACOTADAS a
   `#dashboard_sidebar`: arregla la fuga sin renombrar nada y sin tocar el JS.
   Ver nota 1.

   CONTRATO CON main.js — NO RENOMBRAR: `sidebar_open` y `float_active` (van en
   el <body>), `submenu_trigger`, `menu_item_wrapper`, `.open`.
   ============================================================================ */

/* ---- Tokens ---------------------------------------------------------------
   El 70 y el 230 estaban escritos A MANO en 11 sitios repartidos por 5 bloques
   de main.css (y el móvil metía un tercer ancho, 50). Ver nota 2. */
:root {
  --sidebar-rail:  70px;    /* colapsada: solo la columna de iconos */
  --sidebar-panel: 230px;   /* expandida: iconos + etiquetas */

  /* Lo que la barra le RESERVA al layout — y NO es lo mismo que su ancho.
     En hover crece POR ENCIMA del contenido (z-index 100) y no lo empuja; a
     ≥1920 sí, porque está abierta siempre. Esa diferencia estaba implícita en
     el CSS viejo y era la causa de un bug: ver nota 4. Lo consumen
     `#dashboard_page_content` y el inset del lightbox, los dos desde main.css
     (el PRODUCTO cablea; el DS del lightbox no sabe que existe una barra). */
  --sidebar-reserved: var(--sidebar-rail);

  /* El logo colapsado: dónde empieza y cuánto asoma. */
  --sidebar-logo-x:    20px;
  --sidebar-logo-peek: 30px;

  /* Velos sobre la superficie de marca. No son colores del DS: son sombra
     encima del preset, y por eso viven aquí y no en semantics.css — su valor
     depende de que el fondo sea oscuro. */
  --sidebar-veil:        rgba(0, 0, 0, 0.2);   /* hover / realce del logo */
  --sidebar-veil-subtle: rgba(0, 0, 0, 0.1);   /* submenú hundido */
}

@media (max-width: 768px) {
  :root {
    --sidebar-rail:      50px;
    --sidebar-logo-x:    12px;
    --sidebar-logo-peek: 28px;
  }
}

@media (min-width: 1920px) {
  /* Abierta siempre: aquí sí reserva su ancho completo. */
  :root { --sidebar-reserved: var(--sidebar-panel); }
}

/* ---- La barra -------------------------------------------------------------- */

#dashboard_sidebar {
  --sidebar-open: 0;   /* el interruptor. Ver nota 2. */

  position: fixed;
  top: 0;
  left: 0;
  width: calc(var(--sidebar-rail) + (var(--sidebar-panel) - var(--sidebar-rail)) * var(--sidebar-open));
  height: 100vh;
  overflow-x: hidden;
  background: var(--wp--preset--color--custom-600, var(--wp--preset--color--custom-color-600));
  color: var(--neutral-white);
  z-index: 100;
  transition: all 0.3s;
}

/* LOS TRES DISPARADORES. Lo único que hacen es encender el interruptor — el
   significado de "abierta" se define UNA vez, más abajo. Ver nota 2. */
@media (hover: hover) and (pointer: fine) {
  #dashboard_sidebar:hover { --sidebar-open: 1; }
}
@media (pointer: coarse) {
  .sidebar_open #dashboard_sidebar { --sidebar-open: 1; }
}
@media (min-width: 1920px) {
  #dashboard_sidebar { --sidebar-open: 1; }
}

/* ---- Logo ------------------------------------------------------------------ */

#dashboard_logo {
  height: 70px;
  margin: 15px 0;
}

/* El realce que aparece detrás del logo al abrir. */
#dashboard_logo::before {
  content: '';
  position: absolute;
  top: 0;
  left: 10px;
  height: 70px;
  width: var(--sidebar-panel);
  background: var(--sidebar-veil);
  border-radius: var(--radius-md);
  opacity: var(--sidebar-open);
  transition: all 0.3s;
}

/* Colapsada asoma solo la marca (`--sidebar-logo-peek`) pegada a la izquierda;
   abierta se centra y se ve entero. Las tres propiedades interpolan con el
   interruptor en vez de repetirse por disparador. Ver nota 2. */
#dashboard_logo a {
  display: inline-block;
  position: absolute;
  top: 50%;
  left: 20px;
  height: 35px;
  background-size: contain;
  background-position: 0;
  background-repeat: no-repeat;
  transform: translateY(-50%);
  clip-path: inset(0 calc((100% - var(--sidebar-logo-peek)) * (1 - var(--sidebar-open))) 0 0);
  transition: all 0.3s;
}

/* ---- Lista ----------------------------------------------------------------- */

#dashboard_menu_wrapper {
  width: var(--sidebar-panel);
}

#dashboard_menu {
  max-height: calc(100dvh - 136px);   /* 70 del logo + 30 de sus márgenes + el pie */
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: auto;
}

#dashboard_sidebar .menu_item_wrapper {
  height: 60px;
  text-transform: uppercase;
  font-weight: 500;
  font-size: 12px;
  transition: all 0.3s;
}

#dashboard_sidebar .menu_item_wrapper:hover {
  background: var(--sidebar-veil);
}

#dashboard_sidebar .menu-item {
  height: 60px;
}

#dashboard_sidebar .menu-link {
  width: 100%;
  padding: 0 10px;
  line-height: 130%;
}

/* La etiqueta solo existe con la barra abierta. */
#dashboard_sidebar .menu-link span {
  opacity: var(--sidebar-open);
  transition: all 0.3s;
}

/* El icono del ítem. Lleva CAJA a propósito — es la excepción que foundation.css
   contempla, y aquí por partida doble: la caja es una COLUMNA de layout (los 50
   que alinean todas las etiquetas), no un intento de centrar el glifo. Ver nota 3. */
#dashboard_sidebar .menu_item_wrapper a::before {
  font-family: uicons-regular-rounded !important;
  width: 50px;
  height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-style: normal;
  font-weight: normal !important;
  font-variant: normal;
  text-transform: none;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* El ítem activo es el ACENTO DE MARCA. Es lo que pide el Figma y ya estaba
   bien: el preset manda, la capa `--brand-*` del vertical no participa. */
#dashboard_sidebar .menu-item.current-menu-item,
#dashboard_sidebar .current-menu-item + .submenu_trigger {
  background: var(--wp--preset--color--custom-500, var(--wp--preset--color--custom-color-500));
  /* El texto y el glifo, EN BLANCO. Faltaba: sobre el acento de marca heredaban el color de la
     barra, que no está pensado para ese fondo. Va por la ficha `--text-on-color`, que es
     literalmente "lo que se escribe encima de un color" y vale #FFFFFF. */
  color: var(--text-on-color);
}

/* ---- Submenú --------------------------------------------------------------- */

#dashboard_sidebar .submenu_wrapper {
  display: none;
  float: left;
  width: 100%;
  background: var(--sidebar-veil-subtle);
}

#dashboard_sidebar .sub-menu {
  margin: 0;
  padding: 0;
  list-style: none;
  display: none;
}

#dashboard_sidebar .submenu_wrapper .menu_item_wrapper .menu-item {
  padding-left: 60px;
  height: 50px;
}

#dashboard_sidebar .submenu_wrapper .menu_item_wrapper {
  height: 50px;
}

.submenu_trigger {
  position: relative;
  width: 40px;
  height: 60px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  cursor: pointer;

  /* EL RESET DE BOTÓN, aquí y no en un `style=` del front. En PHP esto es un `<i>` y estas cinco
     no le hacen nada; en el front nuevo es un `<button>`, y sin ellas el navegador le pone su
     fondo, su borde y su color de fábrica.
     Estaban en línea, y eso rompía el estado activo: un `style="background:none"` le gana a
     CUALQUIER hoja, así que el chevron del ítem seleccionado se quedaba sin el acento de marca —
     el enlace pintado de rojo y el chevron de al lado transparente. Desde aquí la regla del ítem
     activo, que lleva `#dashboard_sidebar`, gana por especificidad y lo pinta como debe. */
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;

  /* Y LAS CUATRO QUE FALTABAN DEL MISMO RESET. `color: inherit` estaba; éstas no, y por eso el
     espejo cantaba cuatro propiedades distintas en el chevron — no sólo en la caja: en las 43
     pantallas ya selladas, porque esto es la barra lateral. Medido: PHP (un `<i>`) hereda del
     menú `font-weight: 500 · line-height: 24px · text-transform: uppercase · text-align: start`,
     y el `<button>` del front usa los defaults del navegador (400 · normal · none · center).
     Sobre un control que sólo pinta un icono no se ve —el glifo lo declara la regla de abajo— pero
     es una divergencia real, y la que se deja pasar hoy es la que mañana muerde con texto dentro.
     `font-size` NO va aquí: lo fija esta misma regla arriba, a 18px, y heredarlo lo rompería. */
  font-weight: inherit;
  line-height: inherit;
  text-transform: inherit;
  text-align: inherit;
}

/* EL GLIFO DEL CHEVRON DECLARA SU TIPOGRAFÍA AQUÍ, y no es opcional.
   La hoja de uicons del CDN solo viste `i[class*=" fi-rr-"]` y `span[...]` — por elemento, no por
   clase. En las pantallas de PHP el disparador es un `<i>` y encaja; en el front nuevo es un
   `<button>` (para que el submenú también se abra con el teclado) y NO encaja: el `::before` caía a
   Montserrat, el navegador buscaba U+E0A1 en las tipografías del sistema y pintaba el glifo que
   encontrara — unas barras negras. Es exactamente la misma razón por la que el icono del ítem
   declara la suya arriba (`.menu_item_wrapper a::before`): la hoja del CDN tampoco viste `<a>`.
   Ojo: no se ve venir en Chromium headless, que no tiene tipografías del sistema y ahí sale un
   cuadro vacío, ni en jsdom, que no carga esta hoja. */
.submenu_trigger::before {
  font-family: uicons-regular-rounded !important;
  font-weight: normal !important;
  font-style: normal;
  z-index: 2;
}

/* `.open` lo pone main.js en el `.menu_item_wrapper` (el front nuevo, en el mismo). */
.open .submenu_trigger {
  transform: scaleY(-1);
}

.submenu_trigger::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--sidebar-veil-subtle);
  opacity: 0;
  transition: 0.3s;
}

.submenu_trigger:hover::after {
  opacity: 1;
}

/* ---- Pie y toggle táctil --------------------------------------------------- */

#dashboard_sidebar_footer {
  text-align: center;
  margin-top: auto;
  padding: 10px;
  gap: 10px;
}

/* Solo existe en pantallas sin puntero fino; es el que enciende `.sidebar_open`. */
#touch_menu_trigger {
  display: none;
  width: 50px;
  height: 50px;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  transition: all 0.5s;
}

@media (pointer: coarse) {
  #touch_menu_trigger { display: inline-flex; }
}

.sidebar_open #touch_menu_trigger {
  transform: rotate(180deg);
}

#menu_current_version {
  font-size: 10px;
  opacity: 0.5;
}

/* ---- Móvil ----------------------------------------------------------------
   El riel encoge (los tokens de arriba ya lo dicen) y el ítem pierde su respiro
   lateral porque no cabe. Es lo ÚNICO que el móvil necesita en propio: sus otras
   cuatro reglas —el ancho de la barra, y el logo con su x y su recorte— ahora
   salen de los tokens. */
@media (max-width: 768px) {
  #dashboard_sidebar .menu-link { padding: 0; }
}

/* ---- El hueco que la barra le deja a la página -----------------------------
   Vino de main.css (2026-07-26). Estaba allá por una razón razonable —el hueco es
   del PRODUCTO, no del sistema— pero el front nuevo pinta el mismo marco y NO
   importa main.css a propósito (es el CSS legacy; hay una prueba que lo verifica).
   Dejarlo allá obligaba a copiar estas ocho líneas en React, que es exactamente
   cómo nacieron las divergencias que llevamos la semana pagando (la X del
   lightbox, los iconos).
   Vive aquí porque lo único que necesita saber es cuánto riel reserva la barra, y
   ese token se declara justo arriba. Ver nota 4. */
#dashboard_page_content {
  position: relative;
  top: 0;
  left: var(--sidebar-reserved);
  width: calc(100% - var(--sidebar-reserved));
  min-height: 100vh;
  padding: 15px 15px 30px;
  overflow: hidden;
}

/* En móvil el left/width ya los dan los tokens (el riel son 50); lo único propio
   es el hueco de la cabecera, que ahí flota. */
@media (max-width: 768px) {
  #dashboard_page_content { padding: 85px 15px 15px; }
}

/* ============================================================================
   NOTAS

   1. LA FUGA DE LAS CLASES DE WORDPRESS (medida, no supuesta). `.menu-item`,
      `.sub-menu`, `.menu-link` y `.current-menu-item` se estilaban en main.css
      con reglas GLOBALES (líneas 470-521), y son exactamente las que genera
      `wp_nav_menu()`. El tema registra un bloque que lo llama
      (`gw/navigation-menu`, included-blocks.php:39), así que cualquier menú de
      WordPress del sitio habría heredado el CSS de la barra lateral.
      La pregunta llevaba una fase abierta porque la consulta a la BD falló. Ya
      está contestada, contra los 6 blogs de la red del Local:
        · usos del bloque `gw/navigation-menu` en contenido ...... 0
        · menús `nav_menu` registrados ........................... 0
      O sea: la fuga era real y no le pegaba a nadie. Por eso acotar a
      `#dashboard_sidebar` es seguro HOY y evita que muerda mañana. Se acota en
      vez de renombrar porque renombrar no aportaba nada: el markup es propio y
      el JS depende de varios de estos nombres.
      (De paso: el socket de wp-cli no está en `sites.json` para los Local
      nuevos —el sitio usa el servicio "lightning" y su `mysql` solo trae
      database/user/password—; vive en
      `~/Library/Application Support/Local/run/<id>/mysql/mysqld.sock`. La receta
      del CLAUDE.md asume que está en sites.json y por eso falló. Ver F4.)

   2. EL INTERRUPTOR — por qué existe. La receta de "expandir" (el realce del
      logo, el logo centrado y sin recortar, y las etiquetas visibles) estaba
      COPIADA TRES VECES, una por disparador:
        · @media (hover:hover) and (pointer:fine) → #dashboard_sidebar:hover …
        · @media (pointer:coarse)                 → .sidebar_open #dashboard_sidebar …
        · @media (min-width:1920px)               → #dashboard_sidebar …
      Doce reglas que solo se diferenciaban en el selector. Y no es hipotético:
      el comentario del CSS viejo contaba que ESTO ya lo rompió una vez —la
      expansión colgaba de `.sidebar_open`, que solo activa el toggle táctil, así
      que en desktop no quedaba ninguna regla de hover. Alguien tocó una copia y
      no las otras.
      Ahora hay UN interruptor (`--sidebar-open`, 0|1): los tres disparadores solo
      lo encienden, y lo que SIGNIFICA estar abierta se escribe una vez. Las
      propiedades interpolan con él:
        opacity:   var(--sidebar-open)                          → 0 | 1
        width:     rail + (panel - rail) * open                 → 70 | 230
        left:      logo-x + (50% - logo-x) * open               → 20px | 50%
        transform: translateX(-50% * open)                      → 0 | -50%
        clip-path: inset(0 (100% - peek) * (1 - open) 0 0)      → recortado | entero
      Las transiciones siguen funcionando: una custom property no se anima, pero
      la propiedad que la CONSUME sí recalcula, y su `transition` la ve cambiar.
      Verificado por foto en los 5 estados.
      Murió además el parche que cancelaba el hover en táctil
      (`@media (pointer:coarse){ #dashboard_sidebar:hover{ width: … } }`): con el
      disparador gateado en `(hover:hover) and (pointer:fine)`, en un dispositivo
      de puntero grueso el hover ya no enciende nada. No hay nada que deshacer.

   3. EL ICONO DEL ÍTEM SÍ LLEVA CAJA, Y ESTÁ BIEN. foundation.css dice que por
      defecto un icono va con `font-size` + `line-height:1` y NADA de caja. Aquí
      hay una caja de 50x50 con `line-height:1.5`, y no es el bug de siempre: esa
      caja es una COLUMNA DE LAYOUT — es lo que reserva el ancho del riel y lo que
      alinea todas las etiquetas en la misma x cuando la barra se abre. Sin ella
      cada etiqueta empezaría donde acabara su glifo. La excepción que contempla
      foundation.css ("el padre crece con su contenido") se queda corta para
      describirlo: aquí la caja no centra, MIDE.
      El glifo NO viene de un <i> aparte: las clases `fi fi-rr-…` van en el mismo
      <a> que `.menu-link`, así que el icono es el `::before` del propio enlace.

   4. LA BARRA TIENE DOS ANCHOS Y EL LAYOUT SOLO RESERVA UNO — y ahí había un bug
      REAL, que el token arregla solo. `#dashboard_page_content` se corría 70 y el
      lightbox también (`--lightbox-inset-start: 70px`, main.css). Pero a ≥1920 la
      barra mide 230 y el contenido SÍ se corría a 230 — el lightbox no. Medido:
        1440 → barra 70,  contenido 70,  lightbox 70   ✔
        1920 → barra 230, contenido 230, lightbox 70   ✘ se comía 160 de la barra
      Es un bug PREEXISTENTE: el `.lightbox{left:70px}` de antes de F2d tenía el
      mismo 70 a mano, y F2d lo conservó fiel (que era lo correcto: aquella fase
      movía, no arreglaba). Con `--sidebar-reserved` los dos leen el mismo dato y
      el desajuste no puede volver: quien cambie el ancho lo cambia en un sitio.
      Por eso son DOS conceptos y no uno: `--sidebar-panel` es lo que la barra
      MIDE abierta; `--sidebar-reserved` es lo que le QUITA al contenido. En hover
      crece por encima (no reserva); a ≥1920 reserva. Confundirlos era el bug.

   5. EL ANCHO DEL LOGO ES UN DATO, NO UN ESTILO — y por eso `width:100px` llevaba
      años sin aplicarse. El markup lo pone INLINE desde un ajuste del tenant:
        <a style="background-image:url(…); width:<?php echo $dashboard_logo_width ?>px">
      Un estilo inline le gana a cualquier hoja, así que los DOS `width:100px` de
      main.css (el de base y el del móvil) eran letra muerta: el logo de este
      tenant mide 97 y siempre midió 97. Aquí no se declara.
      Ojo con lo que eso implica para el recorte: el `100%` del `clip-path` es el
      ancho REAL —el del dato—, así que `--sidebar-logo-peek` es "cuántos píxeles
      asoman", medidos desde la izquierda, sea cual sea el logo. Eso es lo que se
      quiere: el trozo que asoma es la marca, no una fracción del logo.
   ============================================================================ */
