/* ==========================================================================
   VELMO · components.css — Design system, capa de COMPONENTES
   Fase 1 del PLAN_REDISENO_UI.md · depende de theme.css
   --------------------------------------------------------------------------
   POR QUE TODO LLEVA PREFIJO .v-
   Los tres ficheros definen .btn, .card y .wrap con valores DISTINTOS entre
   si (.card padding 20px en index, 18px en enterprise, 8px en admin;
   .wrap max-width 940/1100/1150px). Redefinirlos aqui descolocaria las tres
   paginas a la vez, y la Fase 1 se cierra con "ninguna vista se descoloca".

   Por eso esta hoja NO pisa ninguna clase existente: crea la familia nueva
   .v-* en paralelo. La adopcion (sustituir .card por .v-card, .pill/.tag/
   .tp/.est por .v-badge) se hace pagina a pagina en la Fase 4, viendo el
   resultado en cada vista.

   NO renombrar ni reutilizar: .hidden .active .on .open las muta el JS.
   ========================================================================== */


/* ==========================================================================
   1. BOTONES
   ========================================================================== */
.v-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  border:1.5px solid transparent; border-radius:var(--r-md);
  padding:10px var(--sp-4); min-height:40px;
  font-family:inherit; font-size:var(--fs-sm); font-weight:var(--fw-bold);
  line-height:1; white-space:nowrap; cursor:pointer;
  background:#fff; color:var(--navy); border-color:var(--line);
  transition:background var(--t-fast) var(--ease),
             border-color var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease);
}
.v-btn:hover{ border-color:var(--gold); }
.v-btn:active{ transform:translateY(1px); }
.v-btn:disabled,.v-btn[aria-disabled="true"]{ opacity:.55; cursor:default; transform:none; }
.v-btn:disabled:hover{ border-color:var(--line); }

.v-btn--primary{ background:var(--gold); color:var(--navy); border-color:var(--gold); }
.v-btn--primary:hover{ background:var(--gold-d); border-color:var(--gold-d); color:#fff; }

.v-btn--navy{ background:var(--navy); color:#fff; border-color:var(--navy); }
.v-btn--navy:hover{ background:var(--navy2); border-color:var(--navy2); color:#fff; }

.v-btn--ghost{ background:transparent; color:var(--navy); border-color:var(--line); }
.v-btn--ghost:hover{ background:#faf7ef; border-color:var(--gold); }

.v-btn--danger{ background:#fff; color:var(--danger); border-color:#f0c9c9; }
.v-btn--danger:hover{ background:var(--dangerbg); border-color:var(--danger); }

.v-btn--sm{ min-height:32px; padding:6px var(--sp-3); font-size:var(--fs-xs); }
.v-btn--lg{ min-height:48px; padding:13px var(--sp-5); font-size:var(--fs-md); }
.v-btn--block{ width:100%; }

/* Grupo de acciones alineado a la derecha de una cabecera */
.v-actions{ display:flex; flex-wrap:wrap; gap:var(--sp-2); align-items:center; }


/* ==========================================================================
   2. TARJETA
   ========================================================================== */
.v-card{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);
  padding:var(--sp-4);
}
.v-card--flush{ padding:0; overflow:hidden; }      /* para meter una tabla a sangre */
.v-card--raised{ box-shadow:var(--shadow); }

.v-card__head{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--sp-3); flex-wrap:wrap;
  margin:0 0 var(--sp-3);
}
.v-card--flush .v-card__head{ padding:var(--sp-4) var(--sp-4) var(--sp-3); margin:0; }

.v-card__title{
  margin:0; font-size:var(--fs-lg); font-weight:var(--fw-bold);
  color:var(--navy); line-height:var(--lh-tight);
  display:flex; align-items:center; gap:var(--sp-2); min-width:0;
}
.v-card__sub{ margin:var(--sp-1) 0 0; font-size:var(--fs-sm); color:var(--muted); }

/* Cifra de dashboard */
.v-stat__label{ font-size:var(--fs-xs); font-weight:var(--fw-bold); color:var(--muted);
                text-transform:uppercase; letter-spacing:.04em; }
.v-stat__value{ font-size:var(--fs-2xl); font-weight:var(--fw-black); color:var(--navy);
                line-height:var(--lh-tight); margin-top:var(--sp-1); }
.v-stat__value--ok{ color:var(--ok); }
.v-stat__value--warn{ color:var(--warn); }
.v-stat__value--danger{ color:var(--danger); }


/* ==========================================================================
   3. BADGES — familia unica
   Absorbe .tp (tipo de servicio), .tag (estado incidencia), .pill (recibo) y
   .est (estado de cobro). Mismos colores exactos que las cuatro familias
   antiguas, para que la migracion de la Fase 4 no cambie ningun color.
   ========================================================================== */
.v-badge{
  display:inline-flex; align-items:center; gap:var(--sp-1);
  font-size:var(--fs-xs); font-weight:var(--fw-black); line-height:1.6;
  padding:3px 10px; border-radius:var(--r-pill); white-space:nowrap;
  background:var(--neutralbg); color:var(--muted);
}
.v-badge--ok{      background:var(--okbg);      color:var(--ok); }
.v-badge--warn{    background:var(--warnbg);    color:var(--warn); }
.v-badge--danger{  background:var(--dangerbg);  color:var(--danger); }
.v-badge--info{    background:var(--infobg);    color:var(--info); }
.v-badge--neutral{ background:var(--neutralbg); color:var(--muted); }
.v-badge--brand{   background:var(--navy);      color:var(--gold); }
.v-badge--solid{   background:var(--danger);    color:#fff; }        /* = .tag.urg */

/* Tonos de servicio que no encajan en la escala de estado */
.v-badge--purple{ background:#f3ecfb; color:#6b3fa0; }               /* consultoria */
.v-badge--green{  background:#eef7f0; color:#2a7d5f; }               /* alquiler    */

/* Punto de color para semaforos (sustituye a .g/.y/.r/.n de enterprise) */
.v-dot{ width:9px; height:9px; border-radius:50%; display:inline-block; flex:0 0 auto;
        background:var(--muted); }
.v-dot--ok{ background:var(--ok); }
.v-dot--warn{ background:var(--warn); }
.v-dot--danger{ background:var(--danger); }


/* ==========================================================================
   4. TABLA
   En movil pasa a tarjetas apiladas leyendo data-label de cada <td>.
   Es el mismo patron que admin.html ya usa con exito dentro de .card.
   ========================================================================== */
.v-table{ width:100%; border-collapse:collapse; font-size:var(--fs-sm); }
.v-table th,.v-table td{
  padding:10px var(--sp-3); text-align:left; vertical-align:middle;
  border-bottom:1px solid var(--line);
}
.v-table thead th{
  font-size:var(--fs-xs); font-weight:var(--fw-black); color:var(--muted);
  text-transform:uppercase; letter-spacing:.04em; white-space:nowrap;
  background:#fafbfe; border-bottom:1.5px solid var(--line);
  position:sticky; top:0; z-index:var(--z-sticky);
}
.v-table tbody tr:hover{ background:#fafbfe; }
.v-table tbody tr:last-child td{ border-bottom:0; }
.v-table .v-num{ text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; }

/* Envoltorio con scroll horizontal en pantallas intermedias */
.v-table-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }

@media (max-width:900px){ /* = --bp-lg en theme.css (Fase 3); @media no admite var().
  Antes 760px: el barrido de anchos de la Fase 3 encontró que a 768px (iPad en
  vertical, uno de los anchos que hay que probar siempre) se quedaba FUERA por
  8px y la tabla seguía en scroll horizontal — la propia trampa que se estaba
  intentando cerrar. Subido a 900 para tener margen de sobra sobre 768, y de
  paso coincide con el punto en que el sidebar (velmo-nav.js) también se
  recoge: por debajo de 900 todo el panel pasa a modo compacto a la vez, en
  vez de que cada pieza cambie en un punto distinto. */
  .v-table--cards thead{ display:none; }
  .v-table--cards,
  .v-table--cards tbody,
  .v-table--cards tr,
  .v-table--cards td{ display:block; width:auto; min-width:0; }
  /* min-width:0 es a proposito: algunas tablas de origen fijan min-width en
     px para que no se estrujen en horizontal-scroll (p.ej. .bz-tbl de
     enterprise.html, 640px) — sin anularlo aqui, ese min-width sobrevive al
     display:block y la tarjeta seguiria forzando desbordamiento horizontal
     en el movil, justo lo que este componente existe para evitar. */
  .v-table--cards tr{
    background:var(--card); border:1px solid var(--line); border-radius:var(--r-md);
    box-shadow:var(--shadow-sm); margin:0 0 var(--sp-3); padding:var(--sp-2) var(--sp-3);
  }
  /* Fase 4c: .v-table--cards tr (2 clases) gana por especificidad a clases de
     fondo de una sola clase (p.ej. .v-bg-warnrow) puestas sobre la misma <tr> —
     antes lo resolvia el style= inline (maxima especificidad). Override dedicado
     para que la fila conserve su color de aviso tambien en la vista tarjeta. */
  .v-table--cards tr.v-bg-warnrow{ background:#fffaf2; }
  .v-table--cards tr.v-bg-excrow{ background:#fffaf3; }
  .v-table--cards td{ border:0!important; padding:5px 2px!important; text-align:left!important; }
  .v-table--cards td::before{
    content:attr(data-label); display:block;
    font-size:var(--fs-xs); font-weight:var(--fw-bold); color:var(--muted);
    text-transform:uppercase; letter-spacing:.03em; margin-bottom:2px;
  }
  .v-table--cards td[data-label=""]::before,
  .v-table--cards td:not([data-label])::before{ display:none; }
}


/* ==========================================================================
   5. AGRUPACION POR COMUNIDAD  (lo que pide el rediseno: propiedades
   agrupadas y plegables, con los indicadores a la vista)
   Usa <details>/<summary> nativos: sin JS, accesible y sin romper nada.
   ========================================================================== */
.v-group{
  background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-lg); box-shadow:var(--shadow-sm);
  margin-bottom:var(--sp-3); overflow:hidden;
}
.v-group__head{
  display:flex; align-items:center; gap:var(--sp-3); flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4); cursor:pointer; list-style:none;
  transition:background var(--t-fast) var(--ease);
}
.v-group__head::-webkit-details-marker{ display:none; }
.v-group__head:hover{ background:#fafbfe; }

.v-group__caret{
  flex:0 0 auto; width:16px; color:var(--muted);
  transition:transform var(--t-base) var(--ease);
}
.v-group[open] .v-group__caret{ transform:rotate(90deg); }

.v-group__name{
  font-size:var(--fs-md); font-weight:var(--fw-bold); color:var(--navy);
  min-width:0; flex:1 1 220px;                 /* min-width:0 = regla anti-desborde */
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.v-group__count{
  font-size:var(--fs-xs); font-weight:var(--fw-bold); color:var(--muted);
  background:var(--neutralbg); border-radius:var(--r-pill); padding:3px 10px;
}
.v-group__meta{ display:flex; align-items:center; gap:var(--sp-2); flex-wrap:wrap; }
.v-group__body{ padding:0 var(--sp-4) var(--sp-3); border-top:1px solid var(--line); }


/* ==========================================================================
   6. FORMULARIOS
   ========================================================================== */
.v-field{ display:block; margin-bottom:var(--sp-3); min-width:0; }
.v-label{
  display:block; margin-bottom:var(--sp-1);
  font-size:var(--fs-xs); font-weight:var(--fw-bold); color:var(--muted);
  text-transform:uppercase; letter-spacing:.03em;
}
.v-input,.v-select,.v-textarea{
  width:100%; box-sizing:border-box;
  font-family:inherit; font-size:var(--fs-md);  /* 16px: evita el zoom de iOS */
  color:var(--ink); background:#fff;
  border:1.5px solid var(--line); border-radius:var(--r-sm);
  padding:10px var(--sp-3); min-height:42px;
  transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.v-input:focus,.v-select:focus,.v-textarea:focus{
  border-color:var(--gold); box-shadow:0 0 0 3px rgba(194,161,94,.18); outline:none;
}
.v-input:disabled,.v-select:disabled,.v-textarea:disabled{ background:#f7f8fb; color:var(--muted); }
.v-textarea{ min-height:96px; resize:vertical; line-height:var(--lh-base); }
.v-hint{ display:block; margin-top:var(--sp-1); font-size:var(--fs-xs); color:var(--muted); }
.v-hint--error{ color:var(--danger); }

/* Barra de filtros / buscador */
.v-toolbar{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--sp-2);
  margin-bottom:var(--sp-3);
}
.v-search{ position:relative; flex:1 1 260px; min-width:0; }
.v-search .v-input{ padding-left:38px; }
.v-search__ico{
  position:absolute; left:12px; top:50%; transform:translateY(-50%);
  width:16px; height:16px; color:var(--muted); pointer-events:none;
}


/* ==========================================================================
   7. AVISOS  (sustituye a los alert() nativos en la Fase 5)
   ========================================================================== */
.v-alert{
  display:flex; gap:var(--sp-3); align-items:flex-start;
  padding:var(--sp-3) var(--sp-4); border-radius:var(--r-md);
  border:1px solid var(--line); border-left-width:4px;
  background:var(--neutralbg); color:var(--ink);
  font-size:var(--fs-sm); line-height:var(--lh-base);
}
.v-alert--ok{     background:var(--okbg);     border-color:var(--ok);     color:#14563a; }
.v-alert--warn{   background:var(--warnbg);   border-color:var(--warn);   color:#7a4c0b; }
.v-alert--danger{ background:var(--dangerbg); border-color:var(--danger); color:#7d2929; }
.v-alert--info{   background:var(--infobg);   border-color:var(--info);   color:#1e3870; }
.v-alert__ico{ flex:0 0 auto; width:18px; height:18px; margin-top:1px; }


/* ==========================================================================
   8. MODAL
   ========================================================================== */
.v-modal{
  position:fixed; inset:0; z-index:var(--z-modal);
  display:flex; align-items:center; justify-content:center;
  padding:var(--sp-4);
  background:rgba(27,42,74,.45);
  overflow-y:auto;
}
.v-modal__box{
  background:var(--card); border-radius:var(--r-xl); box-shadow:var(--shadow-lg);
  width:100%; max-width:560px; max-height:90vh; overflow:auto;
}
.v-modal__head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:var(--sp-4); border-bottom:1px solid var(--line);
}
.v-modal__title{ margin:0; font-size:var(--fs-lg); font-weight:var(--fw-bold); color:var(--navy); }
.v-modal__body{ padding:var(--sp-4); }
.v-modal__foot{
  display:flex; justify-content:flex-end; gap:var(--sp-2); flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4); border-top:1px solid var(--line); background:#fafbfe;
}
.v-modal__x{
  border:0; background:transparent; color:var(--muted); cursor:pointer;
  font-size:var(--fs-xl); line-height:1; padding:0 var(--sp-1);
}
.v-modal__x:hover{ color:var(--danger); }

@media (max-width:560px){
  .v-modal{ padding:0; align-items:flex-end; }
  .v-modal__box{ max-width:none; border-radius:var(--r-xl) var(--r-xl) 0 0; max-height:94vh; }
  .v-modal__foot .v-btn{ flex:1 1 auto; }
}


/* ==========================================================================
   9. MIGA DE PAN  (admin ya tiene #crumb y setCrumb(): se reutilizan)
   ========================================================================== */
.v-crumb{
  display:flex; align-items:center; gap:var(--sp-2); flex-wrap:wrap;
  font-size:var(--fs-sm); color:var(--muted); margin-bottom:var(--sp-2);
}
.v-crumb a{ color:var(--muted); text-decoration:none; }
.v-crumb a:hover{ color:var(--navy); text-decoration:underline; }
.v-crumb__sep{ color:var(--line); }
.v-crumb__now{ color:var(--navy); font-weight:var(--fw-bold); }


/* ==========================================================================
   10. PAGINACION
   ========================================================================== */
.v-pager{ display:flex; align-items:center; gap:var(--sp-1); flex-wrap:wrap;
          justify-content:center; margin-top:var(--sp-4); }
.v-pager__btn{
  min-width:36px; min-height:36px; padding:0 var(--sp-2);
  display:inline-flex; align-items:center; justify-content:center;
  border:1.5px solid var(--line); border-radius:var(--r-sm); background:#fff;
  color:var(--navy); font-size:var(--fs-sm); font-weight:var(--fw-bold);
  font-family:inherit; cursor:pointer;
}
.v-pager__btn:hover{ border-color:var(--gold); }
.v-pager__btn[aria-current="page"]{ background:var(--navy); border-color:var(--navy); color:#fff; }
.v-pager__btn:disabled{ opacity:.45; cursor:default; }
.v-pager__info{ font-size:var(--fs-xs); color:var(--muted); margin:0 var(--sp-2); }


/* ==========================================================================
   11. ESTADO VACIO
   ========================================================================== */
.v-empty{
  text-align:center; padding:var(--sp-6) var(--sp-4); color:var(--muted);
}
.v-empty__ico{ width:40px; height:40px; color:var(--line); margin:0 auto var(--sp-3); display:block; }
.v-empty__title{ font-size:var(--fs-md); font-weight:var(--fw-bold); color:var(--navy);
                 margin:0 0 var(--sp-1); }
.v-empty__text{ font-size:var(--fs-sm); margin:0 0 var(--sp-4); }


/* ==========================================================================
   12. CARGANDO
   ========================================================================== */
.v-spinner{
  width:18px; height:18px; border-radius:50%; display:inline-block;
  border:2px solid var(--line); border-top-color:var(--gold);
  animation:v-spin .7s linear infinite;
}
@keyframes v-spin{ to{ transform:rotate(360deg); } }

.v-skeleton{
  background:linear-gradient(90deg,#eef1f6 25%,#f6f8fb 37%,#eef1f6 63%);
  background-size:400% 100%; border-radius:var(--r-sm);
  animation:v-shimmer 1.4s ease infinite; min-height:14px;
}
@keyframes v-shimmer{ 0%{background-position:100% 0} 100%{background-position:0 0} }


/* ==========================================================================
   13. REJILLA Y UTILIDADES MINIMAS
   min-width:0 en todos los hijos: es la regla que cerro la auditoria de
   desbordes en movil (ver memoria velmo-auditoria-desbordes-movil).
   ========================================================================== */
.v-grid{ display:grid; gap:var(--sp-3); }
.v-grid>*{ min-width:0; }
.v-grid--2{ grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); }
.v-grid--3{ grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); }
.v-grid--4{ grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); }

.v-row{ display:flex; align-items:center; gap:var(--sp-2); flex-wrap:wrap; min-width:0; }
.v-spacer{ flex:1 1 auto; }
.v-muted{ color:var(--muted); }
.v-nowrap{ white-space:nowrap; }
.v-truncate{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.v-sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Atomos de texto/caja, para sustituir los style="" mas repetidos de la
   Fase 4 (valores literales, no la escala --sp-*, para no alterar ni un
   pixel de lo que ya habia). */
.v-tac{ text-align:center; }
.v-tar{ text-align:right; }
.v-cursor{ cursor:pointer; }
.v-block{ display:inline-block; }
.v-dblock{ display:block; }
.v-flex1{ flex:1; }
.v-pre-line{ white-space:pre-line; }
.v-mono{ font-family:monospace; }
.v-fw4{ font-weight:400; }
.v-fw5{ font-weight:500; }
.v-fw7{ font-weight:700; }
.v-fw8{ font-weight:800; }
.v-fs10{ font-size:10px; }
.v-fs11{ font-size:11px; }
.v-fs12{ font-size:12px; }
.v-fs13{ font-size:13px; }
.v-fs14{ font-size:14px; }
.v-lh15{ line-height:1.5; }
.v-lh17{ line-height:1.7; }
.v-mt-2{ margin-top:2px; }
.v-mt-4{ margin-top:4px; }
.v-mt-3{ margin-top:3px; }
.v-mt-6{ margin-top:6px; }
.v-mt-8{ margin-top:8px; }
.v-mt-10{ margin-top:10px; }
.v-mt-12{ margin-top:12px; }
.v-mt-14{ margin-top:14px; }
.v-mt-16{ margin-top:16px; }
.v-mt-18{ margin-top:18px; }
.v-mt-20{ margin-top:20px; }
.v-mt-22{ margin-top:22px; }
.v-mb-4{ margin-bottom:4px; }
.v-mb-6{ margin-bottom:6px; }
.v-mb-8{ margin-bottom:8px; }
.v-mb-10{ margin-bottom:10px; }
.v-mb-12{ margin-bottom:12px; }
.v-mb-14{ margin-bottom:14px; }
.v-ml-6{ margin-left:6px; }
.v-ml-8{ margin-left:8px; }
.v-ml-10{ margin-left:10px; }
.v-ml-auto{ margin-left:auto; }
.v-mr-0{ margin-right:0; }
.v-m-0{ margin:0; }
.v-danger{ color:var(--danger); }
.v-ok-text{ color:var(--ok); }
.v-warn-text{ color:var(--warn); }
.v-muted2{ color:#9aa3b2; }
.v-ls02{ letter-spacing:.02em; }
.v-pad-1-6{ padding:1px 6px; }
.v-pad-8-14{ padding:8px 14px; }
.v-pad-14{ padding:14px; }
.v-mh70{ min-height:70px; }
.v-resize-v{ resize:vertical; }
.v-w80px{ width:80px; }
.v-w100px{ width:100px; }
.v-w130px{ width:130px; }
.v-w170px{ width:170px; }
/* Subtitulo explicativo justo bajo un h2 de vista, tirando hacia arriba para
   quedar pegado al titulo (patron repetido en varias vistas de admin.html). */
.v-viewintro{ font-size:13px; color:var(--muted); margin:-6px 0 10px; }
.v-cuadre{ border-radius:10px; padding:10px 14px; font-weight:700; }
.v-cuadre--ok{ background:#e6f5ee; border-left:6px solid #1e7d54; color:#1e7d54; }
.v-cuadre--bad{ background:#fbeaea; border-left:6px solid var(--danger); color:var(--danger); }
.v-r10{ border-radius:10px; }
.v-pad-10-14{ padding:10px 14px; }
.v-fs125{ font-size:12.5px; }
.v-ml-4{ margin-left:4px; }
.v-flex-wrap-gap6-center{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.v-flex-wrap-gap6{ display:flex; gap:6px; flex-wrap:wrap; }
.v-pad-7-12{ padding:7px 12px; }
.v-pad-7-13{ padding:7px 13px; }
.v-pad-12-14{ padding:12px 14px; }
.v-pad-6-10{ padding:6px 10px; }
.v-pad-4-12{ padding:4px 12px; }
.v-pad-3-10{ padding:3px 10px; }
.v-flexrow8{ display:flex; gap:8px; align-items:center; }
.v-pad-7-8{ padding:7px 8px; }
.v-pad-11-8{ padding:11px 8px; }
.v-pad-12-16{ padding:12px 16px; }
.v-pad-14-16{ padding:14px 16px; }
.v-pad-14-18{ padding:14px 18px; }
.v-pad-16-18{ padding:16px 18px; }
.v-fw6{ font-weight:600; }
.v-fs17{ font-size:17px; }
/* gap:10px, no 8px (--sp-2): admin.html/enterprise.html usan 10px en muchas filas
   flex ya existentes, distinto del .v-row de la Fase 1 (8px) — no se toca ese
   componente para no mover nada en index.html, que ya lo usa. */
.v-flexrow{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.v-flexrow-between{ display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.v-wa{ background:#e7f6ec; border-color:#bfe6cd; color:#1e7d54; }
.v-wa-solid{ background:#25d366; color:#fff; }
.v-flex-wrap-gap12-center{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.v-pad-9-14{ padding:9px 14px; }
.v-flexrow6{ display:flex; gap:6px; align-items:center; }
.v-pad-14-18{ padding:14px 18px; }
.v-mb-16{ margin-bottom:16px; }
.v-m-0-0-4{ margin:0 0 4px; }
.v-m-12-0-0{ margin:12px 0 0; }
.v-m-2-0-6{ margin:2px 0 6px; }
.v-m-4-0{ margin:4px 0; }
.v-m-10-0{ margin:10px 0; }
.v-pad-10-12{ padding:10px 12px; }
.v-mt-5{ margin-top:5px; }
.v-flexrow5{ display:flex; align-items:center; gap:5px; }
.v-flex-col-gap6{ display:flex; flex-direction:column; gap:6px; }
.v-flex-gap8-start{ display:flex; gap:8px; align-items:flex-start; }
.v-pad-6-0-border{ padding:6px 0; }
.v-filerow{ display:flex; justify-content:space-between; align-items:center; gap:10px;
  border:1px solid var(--line); border-radius:10px; padding:8px 10px; margin-bottom:6px; }
.v-pad-7-10{ padding:7px 10px; }
.v-mb-5{ margin-bottom:5px; }
.tp.plazo-libre{ background:#eef1f6; color:#6b7688; }
.tp.plazo-vencido{ background:#eceff3; color:#6b7688; }
.tp.plazo-urgente{ background:#f8d7da; color:#842029; font-weight:700; }
.tp.plazo-proximo{ background:#fff3cd; color:#8a6d1f; font-weight:700; }
.tp.plazo-lejano{ background:#e8f0e9; color:#2c6e3f; }
.tp.v-radar-linea{ background:#e9edf6; color:#1B2A4A; }
.v-tdk{ color:var(--muted); font-size:11px; text-transform:uppercase; letter-spacing:.03em; width:30%; vertical-align:top; padding:7px 10px; }
.v-tdv{ font-weight:600; padding:7px 10px; }
.v-m-0-0-6{ margin:0 0 6px; }
.v-btn-neutral2{ background:#eef1f6; color:var(--navy); }
.v-fs40{ font-size:40px; }
.v-navy-text{ color:var(--navy); }
.v-flexrow12{ display:flex; align-items:center; gap:12px; }
.v-gold-bg{ background:var(--gold); color:var(--navy); border-color:var(--gold); }
.v-m-neg6-0-8{ margin:-6px 0 8px; }
.v-radar-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; }
.v-navy-line{ color:var(--navy); border-color:var(--line); }
.v-mh220{ min-height:220px; }
.tp.v-origen-web{ background:#e9dfc4; color:#8a6d1f; }
.tp.v-origen-portal{ background:#eef1f6; color:#6b7688; }
.v-jc-end{ justify-content:flex-end; }
.v-items-end{ align-items:flex-end; }
.v-ink-text{ color:var(--ink,inherit); }
.v-flex-gap22-wrap{ display:flex; gap:22px; flex-wrap:wrap; font-size:13px; }
.v-flex-gap18-wrap{ display:flex; gap:18px; flex-wrap:wrap; align-items:center; }
.v-flex1-w220{ flex:1; min-width:220px; }
.v-quorum-ok{ background:#e6f5ee; border-left:6px solid #1e7d54; }
.v-quorum-warn{ background:#fdf3e2; border-left:6px solid #a86a10; }
.v-dim{ opacity:.6; }
.v-bt-line-pt10{ border-top:1px solid var(--line); padding-top:10px; }
.v-gap8{ gap:8px; }
.v-mh160{ min-height:160px; }
.v-ff-inherit{ font-family:inherit; }
.v-flex-gap20-wrap{ display:flex; gap:20px; flex-wrap:wrap; }
.v-acta-box{ white-space:pre-wrap; font-size:13.5px; background:#faf7ef; border-radius:10px; }
.v-m-neg4-0-10{ margin:-4px 0 10px; }
.v-bt-dash-pt10{ border-top:1px dashed #e9dfc4; padding-top:10px; }
.v-bt-line-dash-pt12{ border-top:1px dashed var(--line); padding-top:12px; }
.v-descbox{ background:#f7f9fc; border:1px solid var(--line); border-radius:10px; }
.v-minw200{ min-width:200px; }
.v-nowrap-cursor-fs13{ white-space:nowrap; cursor:pointer; font-size:13px; }
.v-gold-d-text{ color:var(--gold-dark,#a8874a); }
.v-wba{ word-break:break-all; }
.v-flex0auto{ flex:0 0 auto; }
.v-items-center{ align-items:center; }
/* Fase 4c: atomos nuevos para enterprise.html, tanda Comunidades */
.v-mt-0{ margin-top:0; }
.v-mt-neg6{ margin-top:-6px; }
.v-kpis-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin:12px 0; }
.v-h3-tight{ margin:0 0 4px; color:var(--navy); font-size:16px; }
.v-m-0-0-8{ margin:0 0 8px; }
.v-m-0-0-10{ margin:0 0 10px; }
.v-summary-action{ cursor:pointer; font-weight:700; color:var(--navy); }
.v-search-input{ min-width:250px; padding:7px 10px; border:1px solid var(--line); border-radius:8px; font-size:13px; }
.v-modal-closerow{ display:flex; justify-content:flex-end; padding:10px 14px 0; }
.v-label-check{ display:inline-flex; align-items:center; gap:6px; cursor:pointer; color:var(--navy); }
.v-selcert{ min-width:0; width:100%; max-width:420px; }
.v-goldd-text{ color:var(--gold-d); }
.v-bg-detail{ background:#faf9f5; }
.v-detail-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:6px 18px; font-size:13px; }
.v-pad-12{ padding:12px; }
.v-gridfull-mbneg8{ grid-column:1/-1; margin-bottom:-8px; }
.v-bordercolor-ok{ border-color:var(--ok); }
.v-bordercolor-danger{ border-color:var(--danger); }
.v-badge-ok-alt{ background:#e7f6ec; color:var(--ok); }
.v-badge-danger-alt{ background:#fdecec; color:var(--danger); }
.v-bg-warnrow{ background:#fffaf2; }
.v-m-22-0-4{ margin:22px 0 4px; }
.v-badge-borrador{ background:#eef1f6; color:#3a4456; }
.v-badge-pendientevb{ background:#fdf3e2; color:#a86a10; }
.v-badge-firmado{ background:#e6f4ec; color:#1e7d54; }
.v-alertbox-warn{ margin-top:8px; background:#fdf3e2; border-left:3px solid #a86a10; padding:8px 12px; font-size:12.5px; color:#6b4f10; }
.v-alertbox-danger{ margin-top:8px; background:#fbeaea; border-left:3px solid #b23b3b; padding:8px 12px; font-size:12.5px; color:#7a2020; }
.v-badge-incumplido{ background:#fbeaea; color:#b23b3b; }
.v-m-6-0{ margin:6px 0; }
.v-flex-gap10-wrap-mt10{ display:flex; gap:10px; flex-wrap:wrap; margin-top:10px; }
.v-minw160{ min-width:160px; }
.v-w120{ width:120px; }
.v-w70{ width:70px; }
.v-mt-16{ margin-top:16px; }
.v-flex-gap24-wrap{ display:flex; gap:24px; flex-wrap:wrap; }
.v-notext{ text-decoration:none; }
.v-flex-gap8{ display:flex; gap:8px; }
.v-flex-wrap-gap8{ display:flex; gap:8px; flex-wrap:wrap; }
.v-w100{ width:100%; }
.v-minw0{ min-width:0; }
.v-flexrow-between-gap8{ display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
.v-mt12-bt-pt12{ margin-top:12px; border-top:1px solid var(--line); padding-top:12px; }
.v-checklist-grid{ display:grid; gap:6px; margin-bottom:14px; }
.v-flex-gap8-start{ display:flex; gap:8px; align-items:flex-start; }
.v-opacity5-noclick{ opacity:.5; cursor:not-allowed; }
.v-btn-pdfsm{ padding:8px 14px; font-size:13px; }
.v-m-14-0{ margin:14px 0; }
.v-h3-15{ margin:0 0 8px; color:var(--navy); font-size:15px; }
.v-m-6-0-10{ margin:6px 0 10px; }
.v-input-filter-280{ max-width:280px; padding:7px 10px; border:1px solid #ccd; border-radius:8px; }
.v-m-12-0{ margin:12px 0; }
.v-grid-190{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:10px; }
.v-grid-180{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:10px; }
.v-alignself-end{ align-self:end; }
.v-borderleft-gold{ border-left:3px solid #C29B40; }
.v-pad-4-0-2-12{ padding:4px 0 2px 12px; }
.v-m-12-0-4-fs13-muted{ margin:12px 0 4px; font-size:13px; color:var(--muted); }
.v-flex-center-gap8-wrap-mt6{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:6px; }
.v-maxw340{ max-width:340px; }
.v-m-10-0{ margin:10px 0; }
.v-mt-neg4{ margin-top:-4px; }
.v-addconcept-row{ display:flex; gap:8px; flex-wrap:wrap; align-items:end; margin-top:10px; border-top:1px solid #e3e7ee; padding-top:10px; }
.v-flex1-minw220{ flex:1; min-width:220px; }
.v-flex-gap10-end-wrap{ display:flex; gap:10px; align-items:end; flex-wrap:wrap; }
.v-w170{ width:170px; }
.v-flex-center-gap8-wrap-mb8{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:8px; }
.v-flex-gap14-wrap-end{ display:flex; gap:14px; flex-wrap:wrap; align-items:flex-end; }
.v-input-150{ width:150px; padding:8px; border:1px solid #ccd; border-radius:8px; }
.v-input-170{ width:170px; padding:8px; border:1px solid #ccd; border-radius:8px; }
.v-m-0{ margin:0; }
.v-flex-gap6-wrap{ display:flex; gap:6px; flex-wrap:wrap; }
.v-m-4-0-8{ margin:4px 0 8px; }
.v-addgasto-form{ gap:8px; flex-wrap:wrap; align-items:flex-end; margin:0 0 10px; padding:10px; background:#f4f6fb; border-radius:8px; }
.v-input-230-sm{ width:230px; padding:7px; border:1px solid #ccd; border-radius:7px; }
.v-input-sm7{ padding:7px; border:1px solid #ccd; border-radius:7px; }
.v-input-120-sm{ width:120px; padding:7px; border:1px solid #ccd; border-radius:7px; }
.v-fileinput-220{ padding:6px 0; max-width:220px; }
.v-fs15{ font-size:15px; }
.v-flexrow-between-baseline{ display:flex; justify-content:space-between; flex-wrap:wrap; gap:8px; align-items:baseline; }
.v-tbl-collapse-mt8-fs13{ width:100%; border-collapse:collapse; margin-top:8px; font-size:13px; }
.v-th-left-muted{ text-align:left; color:var(--muted); }
.v-th-right-muted{ text-align:right; color:var(--muted); }
.v-tfoot-total{ font-weight:800; border-top:2px solid var(--gold); padding-top:6px; }
.v-tfoot-total-right{ text-align:right; font-weight:800; border-top:2px solid var(--gold); }
.v-topline-gold{ border-top:2px solid var(--gold); }
.v-borderleft-warn{ border-left:4px solid #a86a10; }
.v-m-0-0-6{ margin:0 0 6px; }
.v-m-0-0-4{ margin:0 0 4px; }
.v-tar-mt8{ text-align:right; margin-top:8px; }
.v-link-wrap{ text-decoration:none; white-space:normal; display:inline-block; }
.v-borderbottom-line{ border-bottom:1px solid var(--line); }
.v-summary-row{ cursor:pointer; padding:8px; display:flex; justify-content:space-between; gap:10px; }
.v-m-6-2-0{ margin:6px 2px 0; }
.v-btn-sm12{ padding:6px 12px; font-size:12px; }
.v-p6-8{ padding:6px 8px; }
.v-p5-8{ padding:5px 8px; }
.v-bb-line{ border-bottom:1px solid var(--line); }
.v-th-center-muted{ text-align:center; color:var(--muted); }
.v-input-56-center{ width:56px; text-align:center; }
.v-borderleft-gold-mb12{ margin-bottom:12px; border-left:4px solid var(--gold); }
.v-flex-wrap-gap8-center{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.v-input-minw190{ padding:6px 10px; border:1px solid #ccd; border-radius:8px; min-width:190px; }
.v-borderleft-danger-mb12{ margin-bottom:12px; border-left:4px solid var(--danger); }
.v-borderleft-ok-mb12{ margin-bottom:12px; border-left:4px solid #1e7d54; }
.v-btn-upload-gold{ cursor:pointer; background:#fff3d6; border-color:#e0c56a; color:#8a6d1a; }
.v-opacity5{ opacity:.5; }
.v-btn-gold-outline{ border-color:#c2a15e; color:#8a6d1a; }
.v-p4-10{ padding:4px 10px; }
.v-minitbl{ width:100%; border-collapse:collapse; font-size:12px; background:#fafbfe; }
.v-mini-empty{ padding:8px 12px; color:var(--muted); font-size:12px; }
.v-lineitem-row{ padding:8px; display:flex; flex-wrap:wrap; justify-content:space-between; gap:10px; border-bottom:1px solid var(--line); }
.v-lineitem-bold{ font-weight:800; border-top:2px solid var(--gold); color:var(--navy); }
.v-summary-row-wrap{ cursor:pointer; padding:8px; display:flex; flex-wrap:wrap; justify-content:space-between; gap:10px; }
.v-strike-fade{ text-decoration:line-through; opacity:.5; }
.v-link-gold-bold{ color:#a8874a; font-weight:700; text-decoration:none; }
.v-aviso-row{ display:flex; justify-content:space-between; align-items:flex-start; gap:10px; padding:8px 0; border-top:1px solid var(--line); }
.v-opacity6{ opacity:.6; }
.v-fw7-fs13-wordbreak{ font-weight:700; font-size:13px; word-break:break-word; }
.v-flex-noshrink{ flex:0 0 auto; }
.v-tbl-collapse-fs13{ width:100%; border-collapse:collapse; font-size:13px; }
.v-w80{ width:80px; }
.v-flex-gap8-mb6-center{ display:flex; gap:8px; margin-bottom:6px; align-items:center; }
.v-flex1-minw0{ flex:1; min-width:0; }
.v-w110{ width:110px; }
.v-badge-anulada{ background:#eceff3; color:#6b7688; }
.v-opacity55{ opacity:.55; }
.v-gridfull{ grid-column:1/-1; }
.v-badge-personal{ background:#eef; color:#556; }
.v-badge-sinclasificar{ background:#fff3d6; color:#8a6d1a; }
.v-bg-excrow{ background:#fffaf3; }
.v-p3-6{ padding:3px 6px; }
.v-badge-round-sm{ border-radius:6px; padding:1px 6px; font-size:11px; font-weight:500; }
.v-borderleft-ok{ border-left:4px solid #1e7d54; }
.v-bg-okcard{ background:#e6f5ee; }
.v-badge-round-sm-bold{ border-radius:6px; padding:1px 6px; font-size:11px; font-weight:700; }
.v-bg-delmark{ background:#fbeaea; }
.v-btn-upload-gold-sm{ padding:2px 8px; cursor:pointer; background:#fff3d6; border-color:#e0c56a; color:#8a6d1a; }
.v-btn-xs{ padding:1px 6px; }
.v-delbar{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:0 0 8px; padding:8px 12px; background:#fbeaea; border-radius:8px; }
.v-sem-box{ display:flex; align-items:center; gap:14px; border-radius:12px; padding:14px 18px; }
.v-sem-ok{ background:#e6f5ee; border-left:6px solid #1e7d54; }
.v-sem-warn{ background:#fff6df; border-left:6px solid #8a6d1a; }
.v-sem-danger{ background:#fbeaea; border-left:6px solid #b23b3b; }
.v-sem-icon{ font-size:26px; line-height:1; }
.v-sem-body{ flex:1; min-width:0; }
.v-sem-title{ font-weight:800; font-size:15px; }
.v-sem-ok .v-sem-title, .v-sem-ok .v-sem-pct{ color:#1e7d54; }
.v-sem-warn .v-sem-title, .v-sem-warn .v-sem-pct{ color:#8a6d1a; }
.v-sem-danger .v-sem-title, .v-sem-danger .v-sem-pct{ color:#b23b3b; }
.v-sem-desc{ margin-top:2px; }
.v-sem-pctwrap{ text-align:right; white-space:nowrap; }
.v-sem-pct{ font-size:22px; font-weight:800; }
.v-sem-bartrack{ height:8px; background:#00000012; border-radius:99px; margin-top:8px; overflow:hidden; }
.v-sem-barfill{ height:100%; border-radius:99px; }
.v-sem-ok .v-sem-barfill{ background:#1e7d54; }
.v-sem-warn .v-sem-barfill{ background:#8a6d1a; }
.v-sem-danger .v-sem-barfill{ background:#b23b3b; }
.v-mt4-fw6-muted{ margin-top:4px; font-weight:600; color:var(--muted); }
.v-border0{ border:0; }
.v-m-8-0-0{ margin:8px 0 0; }
.v-btn-inline{ display:inline-block; text-decoration:none; }
.v-flex1{ flex:1; }
.v-m-p4em-0-0{ margin:.4em 0 0; }
.v-selbar{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:0 0 8px; padding:8px 12px; background:#fff3d6; border-radius:8px; }
.v-gold-text{ color:#8a6d1a; }
.v-bg-selrow{ background:#fff3d6; }
.v-float-right-muted-fw7{ float:right; color:var(--muted); font-weight:700; }
.v-inlineblock-mt2{ display:inline-block; margin-top:2px; }
.v-sectitle{ color:var(--navy); font-size:14px; margin:16px 0 6px; }
.v-m-6-0-12-flex-gap8-center-wrap{ margin:6px 0 12px; display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.v-m-neg6-0-10{ margin:-6px 0 10px; }
.v-m-neg6-0-8{ margin:-6px 0 8px; }
.v-mb-12-fw7{ margin:0 0 12px; font-weight:700; }
.v-m-neg2-0-8{ margin:-2px 0 8px; }
.v-m-2-0-8{ margin:2px 0 8px; }
.v-flex-gap8-center-wrap-mb10{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px; }
.v-select-sm{ border:1.5px solid var(--line); border-radius:8px; padding:6px 8px; font-size:13px; }
.v-m-8-0-2{ margin:8px 0 2px; }
.v-chip-active{ background:var(--navy); color:#fff; }
.v-chip-inactive{ background:#eef1f6; color:var(--navy); }
.v-opacity45-noclick{ opacity:.45; cursor:not-allowed; }
.v-m-14-0-6{ margin:14px 0 6px; }
.v-m-p2em-0-p6em{ margin:.2em 0 .6em; }
.v-w-msgmodal{ width:min(680px,100%); }
.v-m-p2em-0-p8em{ margin:.2em 0 .8em; }
.v-m-neg2-0-10{ margin:-2px 0 10px; }
.v-flex-gap8-wrap-mb10{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:10px; }
.v-textarea-msg{ min-height:230px; resize:vertical; font-family:inherit; line-height:1.5; }
.v-navy-fw7-mb4{ color:var(--navy); font-weight:700; margin-bottom:4px; }
.v-textarea-msgraw{ min-height:180px; resize:vertical; font-family:inherit; line-height:1.5; }
.v-alignself-center{ align-self:center; }


/* ==========================================================================
   14. SIDEBAR DE NAVEGACION (Fase 2 — inyectado por web/velmo-nav.js)
   Solo lo usan admin.html y enterprise.html. index.html conserva sus chips
   sticky con IntersectionObserver (portal del vecino, mayoritariamente
   movil) — ver §3.5 de PORTAL/PLAN_REDISENO_UI.md.

   El script lo inyecta como PRIMER hijo de #app, así que hereda el
   .hidden de #app sin CSS aparte: no se ve en login/loading/denied.

   Navy + dorado: mismo maridaje que ya usaba .tp.administracion en
   admin.html (fondo #1B2A4A, texto #c2a15e) — no es una paleta nueva,
   es aplicar a un componente grande un pareo que ya existía a pequeña
   escala en este mismo código.
   ========================================================================== */
:root{ --v-nav-w:248px; --v-nav-bp:900px; }

.v-nav{
  position:fixed; inset:0 auto 0 0; width:var(--v-nav-w); z-index:var(--z-nav);
  background:var(--navy); color:rgba(255,255,255,.86);
  display:flex; flex-direction:column;
  box-shadow:2px 0 0 rgba(0,0,0,.04);
}
/* Logo y etiqueta APILADOS (columna, no fila) — ver el comentario en
   velmo-nav.js: "Administración" no tiene espacios y no puede bajar de
   línea, así que compartiendo fila con el logo (~127px de los 248px del
   sidebar) se salía de la caja. Apilado, el texto tiene el ancho completo. */
.v-nav__brand{
  flex:0 0 auto; display:flex; flex-direction:column; align-items:center;
  gap:2px; padding:var(--sp-4) var(--sp-3); cursor:pointer; text-align:center;
  border-bottom:1px solid rgba(255,255,255,.10);
}
.v-nav__brand img{ height:28px; max-width:100%; margin-bottom:2px; }
.v-nav__brand-title{ font-size:12.5px; font-weight:800; color:#fff; line-height:1.25; }
.v-nav__brand-sub{ font-size:10px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--gold); line-height:1.3; }

.v-nav__body{ flex:1 1 auto; overflow-y:auto; padding:var(--sp-3) var(--sp-2); }
.v-nav__group-label{
  padding:var(--sp-4) var(--sp-3) var(--sp-1); font-size:10.5px; font-weight:800;
  letter-spacing:.08em; text-transform:uppercase; color:rgba(255,255,255,.42);
}
.v-nav__group-label:first-child{ padding-top:var(--sp-2); }

.v-nav__item{
  display:flex; align-items:center; gap:var(--sp-2); width:100%;
  padding:9px var(--sp-3); margin:1px 0; border:0; background:transparent;
  border-radius:var(--r-sm); border-left:3px solid transparent;
  color:rgba(255,255,255,.82); font:inherit; font-size:13.5px; font-weight:600;
  text-align:left; text-decoration:none; cursor:pointer; line-height:1.3;
}
.v-nav__item:hover{ background:rgba(255,255,255,.07); color:#fff; }
.v-nav__item.active{
  background:rgba(194,161,94,.16); border-left-color:var(--gold); color:#fff;
}
.v-nav__item.active .v-nav__ico{ color:var(--gold); }
.v-nav__item--accent{ background:rgba(194,161,94,.12); }
.v-nav__ico{ flex:0 0 auto; width:18px; height:18px; color:rgba(255,255,255,.55); }
.v-nav__label{ flex:1 1 auto; min-width:0; }
.v-nav__badge{
  flex:0 0 auto; background:var(--gold); color:var(--navy); font-size:11px;
  font-weight:800; border-radius:var(--r-pill); padding:1px 7px; line-height:1.5;
}
.v-nav__badge--alarm{ background:var(--danger); color:#fff; }

.v-nav__foot{
  flex:0 0 auto; padding:var(--sp-2); border-top:1px solid rgba(255,255,255,.10);
}

/* El botón hamburguesa y el fondo de cierre: solo existen por debajo del punto
   de corte (ver JS, que los crea igualmente en escritorio pero display:none
   los oculta aquí). */
.v-nav-toggle{
  display:none; position:fixed; top:12px; left:12px; z-index:calc(var(--z-nav) + 1);
  width:40px; height:40px; align-items:center; justify-content:center;
  background:var(--navy); color:#fff; border:0; border-radius:var(--r-sm);
  box-shadow:var(--shadow);
}
.v-nav-toggle svg{ width:20px; height:20px; }
/* z-index por DEBAJO del sidebar (var(--z-nav)): el backdrop cubre toda la
   pantalla y solo tiene que oscurecer el contenido, no puede quedar encima
   del propio panel o le roba los clics a sus botones (bug real, cazado al
   verificar esta fase: el toggle se apagaba pero la vista nunca cambiaba). */
.v-nav-backdrop{ display:none; position:fixed; inset:0; z-index:calc(var(--z-nav) - 1);
  background:rgba(15,23,42,.45); }

/* Escritorio: el contenido de #app se corre a la derecha del sidebar fijo.
   Se aplica a #app (no a body): así login/loading/denied, que no son hijos
   del mismo flujo que el sidebar, no se ven afectados. */
body.v-has-nav #app{ padding-left:var(--v-nav-w); }
body.v-has-nav .topbar{ display:none; }

@media (max-width:900px){
  .v-nav{
    transform:translateX(-100%); transition:transform var(--t-base) var(--ease);
    box-shadow:var(--shadow-lg);
  }
  body.v-nav--open .v-nav{ transform:translateX(0); }
  .v-nav-toggle{ display:flex; }
  /* Con el panel abierto, la hamburguesa quedaría encima del logo del propio
     sidebar (los dos nacen en la misma esquina). Se oculta: ya hay tres formas
     de cerrar (tocar fuera, Esc, elegir una sección) sin ese botón. */
  body.v-nav--open .v-nav-toggle{ display:none; }
  body.v-has-nav.v-nav--open .v-nav-backdrop{ display:block; }
  /* En móvil el sidebar es off-canvas: no reserva hueco, y el botón hamburguesa
     ya ocupa la esquina donde antes estaba el logo del topbar oculto. */
  body.v-has-nav #app{ padding-left:0; padding-top:56px; }
}
