/* ════════════════════════════════════════════════════════════════
   rail.css — Rail global de apps (F0 B3 · Aluna Workspace)
   docs/PLAN_F0_SHELL.md §2 · docs/PLAN_ALUNA_WORKSPACE.md D81-D83, D116

   Columna fija izquierda ~52px estilo Outlook con las apps de Aluna.
   Consume los tokens de la capa productividad (css/tokens-productivity.css:
   --surface-*, --divider) y la marca tenant-editable (--brand-*).
   El sidebar existente pasa a ser el PANEL CONTEXTUAL de la app activa:
   js/rail.js pone data-rail-app="<app>" en .app-shell y aquí se filtra.

   Móvil (≤768px): el rail NO existe — la navegación es la bottom-bar y el
   sheet "Más" existentes (Home se integró como item bn-global). El drawer
   y el bottom-sheet quedan intactos.
   ════════════════════════════════════════════════════════════════ */

/* ── 1 · El rail ─────────────────────────────────────────────────── */
.app-rail { display:none; }

@media (min-width:769px){
  .app-rail {
    display:flex;
    flex-direction:column;
    align-items:center;
    flex:0 0 52px;
    width:52px;
    padding:8px 0;
    /* IOS-4 (audit F0): mismo patrón que .sidebar en css/app.css — deja espacio para el
       home-indicator/gesture-bar de iOS en vez de que el último botón quede tapado. */
    padding-bottom:calc(8px + env(safe-area-inset-bottom,0px));
    gap:2px;
    background:var(--surface-1, var(--bg-surface));
    border-right:1px solid var(--divider, var(--bg-border));
    overflow-y:auto;
    overflow-x:hidden;
    /* PCH-1 (audit F0): en viewports cortos (1366×768, 1280×720, 1080p@150%) el grupo de
       abajo (➕/⚙️/Larry) puede quedar bajo el fold. El rail YA era scrollable
       (overflow-y:auto) pero el scrollbar iba oculto (scrollbar-width:none +
       ::-webkit-scrollbar{display:none}) — sin pista visual de que había más abajo. Fix:
       scrollbar fino y visible + una sombra interior inferior como insinuación permanente
       "hay más abajo" (CSS puro, sin JS de detección de overflow: inocua cuando no hay
       overflow, ya que es solo un borde sombreado de 8px). */
    scrollbar-width:thin;
    box-shadow:inset 0 -8px 8px -8px rgba(0,0,0,.18);
  }
  /* Pulido en vivo (2026-07-12, reporte usuario): el thumb solo se pinta al pasar el
     mouse/enfocar el rail (patrón "overlay scrollbar" de macOS) — en reposo se ve limpio;
     la sombra inset ya avisa "hay más abajo" sin necesidad de un thumb siempre visible. */
  .app-rail::-webkit-scrollbar { width:5px; }
  .app-rail::-webkit-scrollbar-thumb { background:transparent; border-radius:3px; }
  .app-rail::-webkit-scrollbar-track { background:transparent; }
  .app-rail:hover::-webkit-scrollbar-thumb,
  .app-rail:focus-within::-webkit-scrollbar-thumb { background:var(--divider, var(--bg-border)); }
}

.arail-group { display:flex; flex-direction:column; align-items:center; gap:2px; }
.arail-spacer { flex:1 1 auto; min-height:8px; }
.arail-sep {
  width:26px; height:1px; flex:0 0 1px;
  background:var(--divider, var(--bg-border));
  margin:5px 0;
}

/* Botón de app: target táctil 44×44 dentro del rail de 52px */
.arail-btn {
  position:relative;
  width:44px; height:44px;
  min-width:44px; min-height:44px;
  display:flex; align-items:center; justify-content:center;
  border:none; background:transparent;
  border-radius:10px;
  cursor:pointer;
  padding:0;
  color:var(--text);
  font-family:inherit;
}
.arail-btn:hover  { background:var(--surface-2, var(--bg-raised)); }
.arail-btn:active { background:var(--surface-3, var(--bg-raised)); }
/* AND-5 (backlog LOW histórico): Material 3 exige 48dp mínimo en Android, 44px se quedaba corto.
   El rail mide 52px de ancho total (comentario de arriba) — 48px deja solo 2px de margen por
   lado, todavía cabe sin recortar hover/focus-ring. Solo Android (data-os, js/api-fetch.js#
   detectEnvironment) — iOS/desktop mantienen 44px, ya validado ahí. */
:root[data-os="android"] .arail-btn {
  width:48px; height:48px; min-width:48px; min-height:48px;
}
.arail-btn:focus-visible {
  outline:2px solid var(--brand-primary, var(--yt-orange, #C7F000));
  outline-offset:2px;
}
/* UXU-2/PG-1 (Sprint A): antes span+emoji con font-size; ahora <svg stroke="currentColor"> del
   mismo sistema que .nav-icon — hereda color:var(--text) de .arail-btn, así que el hover/active
   ya tiñe el trazo (los emojis nunca respondían a `color`). */
.arail-ico { width:21px; height:21px; flex-shrink:0; pointer-events:none; }

/* Estado activo: tinte + barrita de acento con la marca del tenant */
.arail-btn.active {
  background:color-mix(in srgb, var(--brand-primary, #C7F000) 14%, transparent);
}
.arail-btn.active::before {
  content:'';
  position:absolute; left:-4px; top:10px; bottom:10px;
  width:3px; border-radius:2px;
  background:var(--brand-primary, var(--yt-orange, #C7F000));
}

/* Badge (no-leídos) — DOM+API listos; Correo/Chat cableados a 0 hasta F1/F4.
   UXU-6 (audit F0): texto blanco sobre --brand-secondary (#FF8A5B) da ≈2.3:1, por debajo del
   4.5:1 que exige WCAG AA para texto normal (12px, ni siquiera 12px bold cuenta como "grande").
   Fix: se oscurece el acento con color-mix manteniendo el tono/marca del tenant.
   AND-7 (backlog LOW histórico): la mezcla original (55% acento + 45% negro) solo se validó
   contra el default #FF8A5B (~6.6:1) — --brand-secondary es configurable por tenant
   (js/settings.js/js/events.js la escriben en runtime), así que un tenant con un acento MUY claro
   podía seguir cayendo bajo 4.5:1 con ese mismo 45%. CSS no puede calcular luminancia real en
   tiempo de mezcla (sin contrast-color(), soporte inconsistente aún), así que en vez de validar
   caso por caso se sube el margen de negro a 60% — con el peor caso posible (acento blanco puro)
   la mezcla resultante (~#666) ya da ≈5.8:1, por encima del piso AA para CUALQUIER acento posible,
   no solo el default. */
.arail-badge {
  position:absolute; top:3px; right:3px;
  min-width:16px; height:16px;
  padding:0 4px;
  border-radius:9px;
  display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--brand-secondary, #FF8A5B) 40%, #000 60%);
  color:#fff;
  font-size:12px; font-weight:700; line-height:1;
  font-family:Inter, -apple-system, sans-serif;
  box-sizing:border-box;
}
.arail-badge[hidden] { display:none; }

/* Larry al fondo del rail */
.arail-larry-img {
  width:28px; height:28px;
  border-radius:50%;
  object-fit:cover;
  pointer-events:none;
}

@media print { .app-rail { display:none !important; } }

/* ── 2 · Menú "➕ Nuevo" (D83) ───────────────────────────────────── */
.rail-new-menu {
  position:fixed;
  z-index:var(--z-drawer, 1200);
  min-width:210px;
  padding:6px;
  background:var(--surface-1, var(--bg-surface));
  border:1px solid var(--divider, var(--bg-border));
  border-radius:12px;
  box-shadow:0 14px 44px rgba(0,0,0,.30);
  display:none;
}
.rail-new-menu.open { display:block; }
.rail-new-title {
  font-size:12px; font-weight:700;
  color:var(--text-muted);
  text-transform:uppercase; letter-spacing:.4px;
  padding:6px 10px 4px;
}
.rail-new-item {
  display:flex; align-items:center; gap:9px;
  width:100%;
  border:none; background:transparent;
  border-radius:8px;
  padding:9px 10px;
  min-height:38px;
  font-size:13px; font-weight:500;
  color:var(--text);
  cursor:pointer;
  text-align:left;
  font-family:inherit;
}
.rail-new-item:hover:not(:disabled)  { background:var(--surface-2, var(--bg-raised)); }
.rail-new-item:focus-visible {
  outline:2px solid var(--brand-primary, var(--yt-orange, #C7F000));
  outline-offset:-2px;
}
.rail-new-item:disabled { cursor:not-allowed; opacity:.55; }
.rail-new-ico { font-size:16px; line-height:1; width:20px; text-align:center; }
.rail-new-hint {
  margin-left:auto;
  font-size:12px;
  color:var(--text-muted);
}
/* CON-2 (audit F0): fila de ayuda al pie del menú ➕ — abre el artículo workspace-shell
   (migración 179) vía data-help-key + el delegado global de js/ui/yt-core.js. */
.rail-new-help {
  border-top:1px solid var(--divider, var(--bg-border));
  margin-top:4px;
  padding-top:11px;
}

/* ── 3 · Panel contextual: el sidebar según la app activa ─────────
   Solo en escritorio/tablet (≥769px, mismo umbral que el rail — Grupo D del
   audit F0: antes el rail arrancaba en 880px pero esta sección seguía en
   880px, así que 769-879px se quedaba sin ESTA filtración; ahora coinciden)
   y NUNCA con el drawer abierto (.sidebar-mobile-open siempre muestra el
   nav completo).                                                     */
@media (min-width:769px){
  /* Apps PIM/placeholder con panel trivial → el sidebar se oculta */
  .app-shell[data-rail-app="home"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="mail"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="calendario"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="contactos"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="tareas"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="chat"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="notas"]:not(.sidebar-mobile-open) .sidebar,
  .app-shell[data-rail-app="tableros"]:not(.sidebar-mobile-open) .sidebar { display:none; }

  /* Reporte en vivo (2026-07-12): el botón "Colapsar" del topbar (#topbar-collapse) no hacía
     NADA perceptible en estas mismas apps — técnicamente sí togglea la clase, pero el sidebar
     que colapsaría YA está display:none arriba, así que no hay nada visible que cambiar.
     Fix correcto: ocultar el botón donde no tiene efecto (no "arreglarlo" — ya funcionaba). */
  .app-shell[data-rail-app="home"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="mail"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="calendario"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="contactos"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="tareas"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="chat"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="notas"]:not(.sidebar-mobile-open) #topbar-collapse,
  .app-shell[data-rail-app="tableros"]:not(.sidebar-mobile-open) #topbar-collapse { display:none; }

  /* Finanzas (modo global): solo su grupo */
  .app-shell.mode-global[data-rail-app="finanzas"]:not(.sidebar-mobile-open) .global-nav .nav-group { display:none; }
  .app-shell.mode-global[data-rail-app="finanzas"]:not(.sidebar-mobile-open) #navgrp-finanzas { display:block; }

  /* Config: solo su grupo */
  .app-shell.mode-global[data-rail-app="config"]:not(.sidebar-mobile-open) .global-nav .nav-group { display:none; }
  .app-shell.mode-global[data-rail-app="config"]:not(.sidebar-mobile-open) #navgrp-config { display:block; }
}

/* ── 4 · Panes placeholder ("llega pronto") + stub del Home ──────── */
.rail-soon, .home-soon {
  display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  text-align:center;
  gap:10px;
  min-height:56vh;
  padding:40px 20px;
}
.rail-soon-ico, .home-soon-ico { font-size:44px; line-height:1; }
/* UXU-7 (audit F0): texto lima (--brand-primary, #C7F000) sobre una superficie clara daba
   ≈1.4:1 en tema claro (el lima es "claro" en luminancia pese a ser saturado) — muy por
   debajo del 4.5:1 de WCAG AA. Fix: texto con --text (par de tema, ≈16.5:1 en claro /
   ≈12.9:1 en oscuro sobre --surface-2) + el acento de marca queda SOLO en el borde. */
.rail-soon-badge {
  font-size:12px; font-weight:700;
  text-transform:uppercase; letter-spacing:.5px;
  color:var(--text);
  background:var(--surface-2, var(--bg-raised));
  border:1px solid color-mix(in srgb, var(--brand-primary, #C7F000) 45%, var(--divider, transparent));
  border-radius:999px;
  padding:3px 12px;
}
.rail-soon-title, .home-soon-title {
  font-size:19px; font-weight:800;
  color:var(--text);
  margin:0;
}
.rail-soon-desc, .home-soon-desc {
  font-size:13.5px; line-height:1.6;
  color:var(--text-muted);
  max-width:440px;
  margin:0;
}
.rail-soon .btn { margin-top:6px; }

/* ── 5 · AND-1 (audit F0): bn-global tenía 6 destinos visibles (Home+Eventos+Contactos+
   Agenda+Notas+Más), por encima del máximo de 5 de Material 3 para una barra inferior.
   Se oculta SOLO la fila visible del botón de Notas — sigue en el DOM (no se tocan sus
   listeners de notas.js) y sigue siendo alcanzable desde "Más": ese sheet (js/shell.js
   collectMoreSections) deriva sus items del sidebar REAL (.global-nav), donde Notas YA
   existe como .nav-subitem independiente del bottom-nav. bn-event (Dashboard/Parrilla/
   Ponentes/Stats + Más = 5) ya cumple el máximo, no se toca. */
@media (max-width:768px){
  .app-shell.mode-global .bottom-nav .bn-global[data-tab="tab-notas"] { display:none; }
}

/* ── 6 · Hoja de atajos de teclado "?" (Grupo A del audit F0 — 6 auditores: IOS-2/PG-1/
   PCH-2/CON-1/UXU-1) ───────────────────────────────────────────────────────────────────
   js/shortcuts.js (showHelp/sheetHtml) pinta .alkbd-ov/.alkbd/.alkbd-hd/.alkbd-row/
   .alkbd-key/.alkbd-hint pero sus estilos vivían en css/tour.css — un duplicado del motor
   yt-tour borrado al integrarlo (decisión #79) y nunca recreado: la hoja se veía sin CSS.
   Diálogo centrado (mismo patrón que .cts-modal-bk de contacts.js: AppModal.overlay crea
   un <dialog class="appmod alkbd-ov">, este archivo solo añade el fondo+centrado) en
   escritorio; bottom-sheet en móvil (mismo criterio que .bottom-sheet de css/app.css). */
.alkbd-ov {
  position:fixed; inset:0;
  z-index:100050;
  background:rgba(15,14,13,.55);
  display:flex; align-items:center; justify-content:center;
  padding:20px;
}
.alkbd {
  /* min() en vez de depender SOLO del padding:20px de .alkbd-ov: dialog.appmod (inyectado por
     AppModal.overlay, ver dialog-service.js) tiene mayor especificidad (elemento+clase) y le
     gana el padding a .alkbd-ov (clase sola) — el mismo patrón que .cts-modal-bk ya en
     producción. Con min(480px, calc(100% - 32px)) el margen de respiro queda garantizado
     pase lo que pase con el padding del overlay. */
  width:100%; max-width:min(480px, calc(100% - 32px)); max-height:82vh;
  overflow-y:auto;
  background:var(--surface-1, var(--bg-surface));
  border:1px solid var(--divider, var(--bg-border));
  border-radius:16px;
  box-shadow:0 24px 60px rgba(0,0,0,.35);
  padding:0 0 16px;
}
.alkbd-hd {
  position:sticky; top:0;
  display:flex; align-items:center; justify-content:space-between;
  gap:12px;
  padding:16px 18px 12px;
  background:var(--surface-1, var(--bg-surface));
  border-bottom:1px solid var(--divider, var(--bg-border));
}
.alkbd-title { margin:0; font-size:16px; font-weight:800; color:var(--text); }
.alkbd-close {
  width:32px; height:32px; min-width:32px; min-height:32px;
  display:flex; align-items:center; justify-content:center;
  border:none; border-radius:8px;
  background:var(--surface-2, var(--bg-raised));
  color:var(--text);
  font-size:14px; line-height:1; cursor:pointer;
}
.alkbd-close:hover { background:var(--surface-3, var(--bg-raised)); }
.alkbd-close:focus-visible { outline:2px solid var(--brand-primary, var(--yt-orange, #C7F000)); outline-offset:2px; }
.alkbd-group { padding:4px 18px 0; }
.alkbd-gtitle {
  margin:14px 0 6px; font-size:12px; font-weight:700;
  text-transform:uppercase; letter-spacing:.5px;
  color:var(--text-muted);
}
.alkbd-row {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; padding:8px 0;
  border-bottom:1px solid var(--divider, var(--bg-border));
  font-size:13px; color:var(--text-2, var(--text));
}
.alkbd-group .alkbd-row:last-child { border-bottom:none; }
.alkbd-desc { flex:1 1 auto; }
.alkbd-combo { display:flex; align-items:center; gap:4px; flex-shrink:0; }
.alkbd-key {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:22px; height:22px; padding:0 6px;
  border-radius:6px;
  background:var(--surface-3, var(--bg-raised));
  border:1px solid var(--divider, var(--bg-border));
  box-shadow:0 1px 0 var(--divider, var(--bg-border));
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:12px; font-weight:600; color:var(--text);
}
.alkbd-then { font-size:12px; color:var(--text-muted); }
.alkbd-hint, .alkbd-empty {
  margin:14px 18px 0; padding-top:10px;
  border-top:1px solid var(--divider, var(--bg-border));
  font-size:12px; line-height:1.5; color:var(--text-muted);
}

/* Móvil: bottom-sheet en vez de diálogo centrado (mismo criterio que css/app.css
   .bottom-sheet-panel — deslizamiento desde abajo + safe-area). */
@media (max-width:640px){
  .alkbd-ov { align-items:flex-end; padding:0; }
  .alkbd {
    max-width:none; width:100%; max-height:86vh;
    border-radius:20px 20px 0 0;
    padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));
  }
}
