/* ============================================================
   SAM — Shell de la app
   Móvil: topbar (mirar) + nav inferior (tocar, zona del pulgar).
   Desktop: rail lateral textual fijo (nada de hamburguesa) +
   contenido ancho. Fondo negro con grid neón sutil.
   ============================================================ */

/* ---- Fondo vivo ---- */
.app-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse 95% 65% at 50% -10%, rgba(var(--c-primary-rgb), 0.16), transparent 72%),
    radial-gradient(ellipse 60% 40% at 90% 110%, rgba(var(--c-secondary-rgb), 0.08), transparent 60%),
    var(--c-black);
}
.app-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(var(--c-primary-rgb), 0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--c-primary-rgb), 0.1) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(ellipse 100% 90% at 50% 0%, #000 35%, transparent 82%);
  -webkit-mask-image: radial-gradient(ellipse 100% 90% at 50% 0%, #000 35%, transparent 82%);
  animation: grid-drift 26s linear infinite;
}
@keyframes grid-drift { to { background-position: 44px 44px, 44px 44px; } }
/* Velocidad del fondo animado, configurable desde /configuracion → Temas
   (theme.bgAnim → <html data-bg-anim>). Sin atributo = normal (26s). */
:root[data-bg-anim='off'] .app-bg::after { animation: none; }
:root[data-bg-anim='slow'] .app-bg::after { animation-duration: 48s; }
:root[data-bg-anim='fast'] .app-bg::after { animation-duration: 10s; }
@media (prefers-reduced-motion: reduce) {
  .app-bg::after { animation: none; }
}
/* Patrón del fondo (theme.bgStyle → <html data-bg-style>). Default: la
   rejilla de arriba. Los tres beben de --c-primary-rgb/--c-secondary-rgb,
   así que siguen al tema activo igual que la rejilla. */
:root[data-bg-style='dots'] .app-bg::after {
  /* matriz de puntos; tamaño 44px = el paso de grid-drift, para que el
     bucle de la animación cierre sin salto */
  background-image: radial-gradient(rgba(var(--c-primary-rgb), 0.22) 1.6px, transparent 1.7px);
  background-size: 44px 44px;
}
:root[data-bg-style='aurora'] .app-bg::after {
  background-image:
    radial-gradient(closest-side, rgba(var(--c-primary-rgb), 0.2), transparent),
    radial-gradient(closest-side, rgba(var(--c-secondary-rgb), 0.14), transparent);
  background-size: 65vmax 65vmax, 55vmax 55vmax;
  background-position: -12vmax -12vmax, 65vw 55vh;
  background-repeat: no-repeat;
  filter: blur(34px);
  mask-image: none;
  -webkit-mask-image: none;
  animation: aurora-drift 26s ease-in-out infinite alternate;
}
@keyframes aurora-drift {
  to { background-position: 34vw 22vh, 12vw 6vh; }
}

/* ---- Layout base ---- */
#app { min-height: 100dvh; display: flex; flex-direction: column; }

.app-topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  min-height: 58px;
  padding: 0 var(--sp-md);
  padding-top: env(safe-area-inset-top, 0px);
  background: rgba(0, 0, 0, 0.72);
  -webkit-backdrop-filter: var(--blur-glass);
  backdrop-filter: var(--blur-glass);
  border-bottom: 1px solid rgba(var(--c-primary-rgb), 0.18);
}
.app-topbar .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--c-heading, #fff);
  font-weight: 800;
  letter-spacing: 2px;
  font-size: 15px;
  text-transform: uppercase;
  text-shadow: 0 0 12px var(--c-primary-text-shadow);
}
.app-topbar .brand img {
  height: 44px;
  width: auto;
  filter: drop-shadow(0 0 8px var(--c-primary-glow));
}
.app-topbar .brand span { font-size: 17px; }
.topbar-spacer { flex: 1; }
.topbar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: 0;
  background: none;
  color: var(--c-text-variant);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  border-radius: var(--r-full);
  cursor: pointer;
}
.topbar-btn:hover { color: var(--c-heading, #fff); background: var(--c-primary-glow-soft); }
/* Icono de apagado (SVG inline: no depende de que el sistema tenga el glifo
   U+23FB, que en Android/iOS no existe y dejaba el boton sin icono). */
.ico-power { width: 16px; height: 16px; flex: 0 0 auto; }
.topbar-btn .ico-power { width: 15px; height: 15px; }
.rail-logout .nav-ico { display: inline-flex; align-items: center; justify-content: center; }

/* ---- Vista (punto de montaje de módulos) ---- */
.app-view {
  flex: 1;
  width: 100%;
  max-width: var(--mobile-max);
  margin: 0 auto;
  padding: var(--sp-md) var(--sp-sm) calc(96px + env(safe-area-inset-bottom, 0px));
  animation: view-in var(--t-slow) var(--ease-out) both;
}
@keyframes view-in { from { opacity: 0; transform: translateY(10px); } }

/* ---- Nav inferior (móvil): textual, thumb-zone ---- */
/* En Inicio el launcher trae su propio dock: la nav flotante se esconde
   (shell.js marca .is-on-home en updateActive). */
.app-nav.is-on-home { display: none; }

.app-nav {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-nav);
  display: flex;
  gap: 2px;
  padding: 6px;
  border-radius: var(--r-full);
  background: var(--c-glass-strong);
  -webkit-backdrop-filter: var(--blur-glass);
  backdrop-filter: var(--blur-glass);
  border: 1px solid var(--c-border-glass);
  box-shadow: var(--glow-primary), 0 8px 30px rgba(0, 0, 0, 0.6);
  max-width: calc(100vw - 16px);
}
.app-nav a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 62px;
  min-height: 52px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  text-decoration: none;
  color: var(--c-text-variant);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  transition: color var(--t-fast), background var(--t-base) var(--ease-out);
  white-space: nowrap;
}
.app-nav a .nav-ico { font-size: 19px; line-height: 1; }
.app-nav a.is-active {
  color: var(--c-on-primary-container, #001a24);
  background: linear-gradient(100deg, var(--c-primary-container), var(--c-secondary-container));
  box-shadow: 0 0 14px var(--c-primary-glow);
}
.app-nav a:not(.is-active):hover { color: var(--c-heading, #fff); background: var(--c-primary-glow-soft); }

/* ---- Desktop (≥900px): rail lateral textual + contenido ancho ---- */
@media (min-width: 900px) {
  #app.has-nav { flex-direction: row; }
  .app-rail {
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100dvh;
    width: 232px;
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: var(--sp-md) var(--sp-xs);
    border-right: 1px solid rgba(var(--c-primary-rgb), 0.18);
    background: rgba(0, 0, 0, 0.5);
    -webkit-backdrop-filter: var(--blur-glass);
    backdrop-filter: var(--blur-glass);
  }
  .app-rail .brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px 18px;
    text-decoration: none;
    color: var(--c-heading, #fff);
    font-weight: 800;
    letter-spacing: 2px;
    text-transform: uppercase;
    font-size: 14px;
    text-shadow: 0 0 12px var(--c-primary-text-shadow);
  }
  .app-rail .brand img {
    height: 42px;
    width: auto;
    filter: drop-shadow(0 0 8px var(--c-primary-glow));
  }
  .app-rail .brand span { font-size: 15px; }
  .app-rail a.rail-link {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 0 14px;
    border-radius: var(--r-md);
    text-decoration: none;
    color: var(--c-text-variant);
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: 0.4px;
    transition: color var(--t-fast), background var(--t-base) var(--ease-out);
  }
  .app-rail a.rail-link .nav-ico { font-size: 17px; width: 22px; text-align: center; }
  .app-rail a.rail-link.is-active {
    color: var(--c-heading, #fff);
    background: rgba(var(--c-primary-rgb), 0.14);
    text-shadow: 0 0 10px var(--c-primary-text-shadow);
  }
  .app-rail a.rail-link:not(.is-active):hover { color: var(--c-heading, #fff); background: var(--c-primary-glow-soft); }

  /* Contenedor de accesos directos configurables (drag & drop desde /home).
     Sin position propia: el rail-indicator mide offsetTop contra .app-rail. */
  .rail-links { display: flex; flex-direction: column; gap: 4px; min-height: 44px; }
  .rail-links a.rail-link--shortcut { cursor: grab; }
  .rail-links a.rail-link--shortcut:active { cursor: grabbing; }
  .rail-links a.rail-link.is-dragging { opacity: 0.35; }

  /* Rail como zona de soltado: marco punteado neón mientras se arrastra encima */
  .app-rail.is-drop-hover {
    outline: 2px dashed var(--c-primary-bright, #38bdf8);
    outline-offset: -6px;
    background: rgba(var(--c-primary-rgb), 0.06);
  }

  /* Sin accesos aún: pista de uso */
  .rail-hint {
    margin: 4px 6px;
    padding: 10px 12px;
    border: 1px dashed rgba(var(--c-primary-rgb), 0.35);
    border-radius: var(--r-md);
    color: var(--c-muted, rgba(255, 255, 255, 0.55));
    font-size: 12px;
    line-height: 1.5;
  }

  /* Indicador de módulo activo: marco neón que VIAJA entre enlaces.
     Lo posiciona shell.js (top/left/width/height); el desplazamiento lo
     anima la transition y el "latido" neón el keyframe rail-neon. */
  .rail-indicator {
    position: absolute;
    pointer-events: none;
    border: 1px solid var(--c-primary-bright);
    border-radius: var(--r-md);
    opacity: 0;
    transition:
      top 0.35s var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
      left 0.35s var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
      width 0.35s var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
      height 0.35s var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
      opacity 0.2s ease;
    animation: rail-neon 2.4s ease-in-out infinite;
  }
  @keyframes rail-neon {
    0%, 100% {
      border-color: rgba(var(--c-primary-rgb), 0.55);
      box-shadow:
        0 0 6px rgba(var(--c-primary-rgb), 0.25),
        inset 0 0 4px rgba(var(--c-primary-rgb), 0.12);
    }
    50% {
      border-color: rgba(var(--c-primary-rgb), 1);
      box-shadow:
        0 0 16px rgba(var(--c-primary-rgb), 0.55),
        inset 0 0 9px rgba(var(--c-primary-rgb), 0.3);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .rail-indicator {
      transition: opacity 0.2s ease;
      animation: none;
      box-shadow: 0 0 10px rgba(var(--c-primary-rgb), 0.4);
    }
  }
  .rail-foot { margin-top: auto; display: flex; flex-direction: column; gap: 4px; }

  .app-main { flex: 1; min-width: 0; }
  .app-view {
    max-width: 1080px;
    padding: var(--sp-lg) var(--sp-xl) var(--sp-section);
  }
  /* En desktop la nav flotante inferior se oculta: manda el rail */
  #app.has-nav .app-nav { display: none; }
  #app.has-nav .app-topbar { display: none; }
}
@media (max-width: 899.98px) {
  .app-rail { display: none; }
}

/* ---- Transición universal de módulos ----
   Salida: la vista entera se desvanece en bloque (core.js añade
   .view-leave y espera). Entrada: las secciones del módulo (nietos del
   contenedor: cabecera, filtros, listas…) hacen fade-in escalonado de
   arriba hacia abajo. */
/* La salida es una ANIMACIÓN (no transition): .app-view ya lleva una
   animación base con fill, y una animación adherida se queda dueña de la
   opacity — una transition sobre la misma propiedad no llega a correr.
   Al añadir la clase, esta animación sustituye a la base y corre limpia. */
.app-view.view-leave { animation: view-leave-out 320ms var(--ease-in) both; }
@keyframes view-leave-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

.app-view.view-enter > * > * {
  animation: view-section-in 0.6s var(--ease-out) both;
  animation-delay: 0.62s; /* secciones más allá de la 8ª entran al final */
}
.app-view.view-enter > * > *:nth-child(1) { animation-delay: 0.05s; }
.app-view.view-enter > * > *:nth-child(2) { animation-delay: 0.13s; }
.app-view.view-enter > * > *:nth-child(3) { animation-delay: 0.21s; }
.app-view.view-enter > * > *:nth-child(4) { animation-delay: 0.29s; }
.app-view.view-enter > * > *:nth-child(5) { animation-delay: 0.37s; }
.app-view.view-enter > * > *:nth-child(6) { animation-delay: 0.45s; }
.app-view.view-enter > * > *:nth-child(7) { animation-delay: 0.53s; }
.app-view.view-enter > * > *:nth-child(8) { animation-delay: 0.61s; }
@keyframes view-section-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .app-view.view-leave { animation: none; }
  .app-view.view-enter > * > * { animation: none; }
  .app-view { animation: none; }
}

/* ---- Cambiar tema: mismo cuerpo que un rail-link, en botón ---- */
.rail-theme {
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font);
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--r-md);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-align: left;
  color: var(--c-text-variant);
  transition: color var(--t-fast), background var(--t-base) var(--ease-out);
}
.rail-theme .nav-ico { font-size: 17px; width: 22px; text-align: center; }
.rail-theme:hover,
.rail-theme:focus-visible {
  color: var(--c-heading, #fff);
  background: var(--c-primary-glow-soft);
}
/* ---- Toggle sol/luna (base Uiverse.io by JkHuger, adaptado a tokens) ----
   checked = oscuro. Sin .theme__fill del original: el wipe de pantalla con
   mix-blend-mode pelearía con el theming real por data-theme. El resto de la
   coreografía (slide del knob, sol→luna con rayos plegándose) queda intacta. */
.theme {
  --transDur: 0.3s;
  --theme-primary: var(--c-primary, #38bdf8);
  --theme-primaryT: color-mix(in srgb, var(--c-primary, #38bdf8) 55%, transparent);
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* La escala em vive en el wrap, NO en .theme: así el texto del label
   ("Modo claro/oscuro") conserva la fuente del rail. Track 42×21px. */
.theme__toggle-wrap { font-size: 7px; }
.theme__text { user-select: none; }
/* En el rail, el label ocupa toda la fila: cualquier punto del item conmuta. */
.rail-theme .theme { width: 100%; min-height: 44px; }
.theme__icon { transition: 0.3s; }
.theme__icon, .theme__toggle { z-index: 1; }
.theme__icon, .theme__icon-part { position: absolute; }
/* Centro del knob: padding .25em + radio 1.25em = 1.5em; icono de 1.5em →
   offset .75em. El .5em del asset original lo dejaba descentrado. */
.theme__icon { display: block; top: 0.75em; left: 0.75em; width: 1.5em; height: 1.5em; pointer-events: none; }
.theme__icon-part {
  border-radius: 50%;
  box-shadow: 0.4em -0.4em 0 0.5em hsl(0, 0%, 100%) inset;
  top: calc(50% - 0.5em);
  left: calc(50% - 0.5em);
  width: 1em;
  height: 1em;
  transition: box-shadow var(--transDur) ease-in-out,
    opacity var(--transDur) ease-in-out,
    transform var(--transDur) ease-in-out;
  transform: scale(0.5);
}
.theme__icon-part ~ .theme__icon-part {
  background-color: hsl(0, 0%, 100%);
  border-radius: 0.05em;
  top: 50%;
  left: calc(50% - 0.05em);
  transform: rotate(0deg) translateY(0.5em);
  transform-origin: 50% 0;
  width: 0.1em;
  height: 0.2em;
}
.theme__icon-part:nth-child(3) { transform: rotate(45deg) translateY(0.45em); }
.theme__icon-part:nth-child(4) { transform: rotate(90deg) translateY(0.45em); }
.theme__icon-part:nth-child(5) { transform: rotate(135deg) translateY(0.45em); }
.theme__icon-part:nth-child(6) { transform: rotate(180deg) translateY(0.45em); }
.theme__icon-part:nth-child(7) { transform: rotate(225deg) translateY(0.45em); }
.theme__icon-part:nth-child(8) { transform: rotate(270deg) translateY(0.5em); }
.theme__icon-part:nth-child(9) { transform: rotate(315deg) translateY(0.5em); }
.theme__toggle, .theme__toggle-wrap { position: relative; }
.theme__toggle, .theme__toggle::before { display: block; }
.theme__toggle {
  /* Lado sol (claro activo): también en el acento del tema — feedback del
     owner 2026-08-11: el amarillo fijo desentonaba con temas no-cálidos. */
  background-color: color-mix(in srgb, var(--c-primary-bright, #38bdf8) 28%, #ffffff);
  border-radius: 25% / 50%;
  box-shadow: 0 0 0 0.125em var(--theme-primaryT);
  padding: 0.25em;
  width: 6em;
  height: 3em;
  margin: 0;
  /* CRÍTICO: los input no heredan font-size; sin esto los em del track se
     calculan a 16px (96×48px gigante) y desalineados con el icono (7px). */
  font-size: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color var(--transDur) ease-in-out,
    box-shadow 0.15s ease-in-out,
    transform var(--transDur) ease-in-out;
}
.theme__toggle::before {
  background-color: var(--c-primary-bright, hsl(48, 90%, 55%));
  border-radius: 50%;
  content: "";
  width: 2.5em;
  height: 2.5em;
  transition: 0.3s;
}
.theme__toggle:focus {
  box-shadow: 0 0 0 0.125em var(--theme-primary);
  outline: transparent;
}
/* Lado luna (oscuro activo): track y knob en el ACENTO del tema — con un tema
   Rubí el toggle es rubí, no el azul de fábrica. El lado sol queda amarillo a
   propósito: el sol es semántica de "claro", no marca. */
.theme__toggle:checked { background-color: color-mix(in srgb, var(--c-primary-bright, #38bdf8) 18%, #06090f); }
.theme__toggle:checked::before,
.theme__toggle:checked ~ .theme__icon { transform: translateX(3em); }
.theme__toggle:checked::before { background-color: var(--c-primary-bright, hsl(198, 90%, 55%)); }
/* Luna centrada: el asset original la desplazaba (.2em/-.2em) porque su icono
   ya venía descentrado; con el icono bien anclado, la luna (1em) se centra en
   la caja de 1.5em con .25em exactos por lado. */
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(1) {
  box-shadow: 0.2em -0.2em 0 0.2em hsl(0, 0%, 100%) inset;
  transform: scale(1);
  top: 0.25em;
  left: 0.25em;
}
.theme__toggle:checked ~ .theme__icon .theme__icon-part ~ .theme__icon-part { opacity: 0; }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(2) { transform: rotate(45deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(3) { transform: rotate(90deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(4) { transform: rotate(135deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(5) { transform: rotate(180deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(6) { transform: rotate(225deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(7) { transform: rotate(270deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(8) { transform: rotate(315deg) translateY(0.8em); }
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(9) { transform: rotate(360deg) translateY(0.8em); }
.theme__toggle-wrap { margin: 0; }
@supports selector(:focus-visible) {
  .theme__toggle:focus { box-shadow: 0 0 0 0.125em var(--theme-primaryT); }
  .theme__toggle:focus-visible { box-shadow: 0 0 0 0.125em var(--theme-primary); }
}
@media (prefers-reduced-motion: reduce) {
  .theme__toggle, .theme__toggle::before, .theme__icon, .theme__icon-part { transition: none !important; }
}
/* ---- Cerrar sesión: latido rojo constante + hover ---- */
.rail-logout {
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font);
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--r-md);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-align: left;
  color: var(--c-text-variant);
  animation: logout-ember 3s ease-in-out infinite;
  transition:
    background var(--t-base) var(--ease-out),
    text-shadow var(--t-fast),
    transform var(--t-fast) var(--ease-out);
}
@keyframes logout-ember {
  0%, 100% { color: var(--c-text-variant); text-shadow: none; }
  50% { color: #ff8a80; text-shadow: 0 0 10px rgba(255, 82, 82, 0.45); }
}
.rail-logout:hover,
.rail-logout:focus-visible {
  animation: none;
  color: #ff8a80;
  background: rgba(255, 82, 82, 0.12);
  text-shadow: 0 0 12px rgba(255, 82, 82, 0.55);
  transform: translateX(2px);
}
.rail-logout:active { transform: translateX(2px) scale(0.98); }
@media (prefers-reduced-motion: reduce) {
  .rail-logout { animation: none; transition: none; }
  .rail-logout:hover, .rail-logout:focus-visible { transform: none; }
}

/* ---- Usuario + campana (pie del rail / topbar) ---- */
.rail-user-row { display: flex; align-items: center; gap: 8px; }
.rail-user-row .rail-link { flex: 1; min-width: 0; }

.rail-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  overflow: hidden;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  background: var(--c-surface-high);
  border: 1px solid var(--c-border-glass);
  color: var(--c-primary);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
.rail-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* Campana (base Uiverse.io by vinodjangid07, adaptada a tokens) */
.bell-btn {
  width: 44px;
  height: 44px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-surface-high);
  border-radius: 50%;
  cursor: pointer;
  transition-duration: 0.3s;
  box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.13);
  border: 1px solid var(--c-outline-variant);
  flex: 0 0 auto;
}
.bell-btn .bell { width: 16px; }
.bell-btn .bell path { fill: var(--c-text); }
.bell-btn:hover { background: var(--c-surface-highest); border-color: var(--c-border-glass); }
.bell-btn:hover .bell { animation: bellRing 0.9s both; }
.bell-btn:active { transform: scale(0.85); }

@keyframes bellRing {
  0%, 100% { transform-origin: top; }
  15% { transform: rotateZ(10deg); }
  30% { transform: rotateZ(-10deg); }
  45% { transform: rotateZ(5deg); }
  60% { transform: rotateZ(-5deg); }
  75% { transform: rotateZ(2deg); }
}

/* Badge de pendientes: oculto cuando el atributo hidden está presente */
.bell-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  background: var(--c-error-container);
  color: var(--c-on-error-container);
  border: 2px solid var(--c-black);
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.bell-badge[hidden] { display: none; }

/* ---- Vista pública (login): centrada, columna 420 ---- */
.auth-screen {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--sp-md);
}
.auth-card { width: min(100%, var(--mobile-max)); padding: var(--sp-xl); }
.auth-logo { display: flex; flex-direction: column; align-items: center; gap: var(--sp-xs); margin-bottom: var(--sp-lg); text-align: center; }
.auth-logo img { height: 162px; width: auto; filter: drop-shadow(0 0 14px var(--c-primary-glow)); }

/* ============================================================
   Modo claro: superficies del chrome que no salen de tokens
   ============================================================ */
:root[data-theme='light'] .app-topbar {
  background: rgba(255, 255, 255, 0.82);
  border-bottom-color: var(--c-border-glass);
}
:root[data-theme='light'] .app-nav {
  box-shadow: var(--glow-primary), 0 8px 30px rgba(15, 23, 42, 0.18);
}
:root[data-theme='light'] .app-nav a.is-active { color: #ffffff; }
:root[data-theme='light'] .app-rail {
  background: rgba(255, 255, 255, 0.66);
  border-right-color: var(--c-border-glass);
}
:root[data-theme='light'] .app-rail a.rail-link.is-active { background: var(--c-primary-glow-soft); }
:root[data-theme='light'] .rail-hint { color: var(--c-text-muted); }
