
        /* Superficie elevada (banner/modal de instalar PWA). Valor oscuro por
           defecto; html.light-mode lo cambia a blanco. Se lee desde estilos
           inline como var(--elev-surface) porque un !important de hoja no pisa
           esos inline en esta página (Tailwind CDN + capas). */
        :root {
            /* Alto real de la barra de navegación inferior — SOLO en el ancho
               donde existe (mobile, `sm:hidden`). Todo lo que hoy vive pegado
               al borde inferior (FAB, botón "Ahora", banners, toasts) suma
               esta variable a su `bottom` para no quedar tapado por la barra.
               Un solo número que cambiar si la barra cambia de alto. */
            --bottom-nav-h: 0px;
        }
        @media (max-width: 639.98px) {
            :root { --bottom-nav-h: 66px; }
        }
        /* El ultimo item de la lista del dia (y de la semana) no debe quedar
           tapado por la barra fija. `pb-24` ya reservaba espacio para el FAB;
           se le suma la barra. */
        @media (max-width: 639.98px) {
            .agenda-primary-column { padding-bottom: calc(6rem + var(--bottom-nav-h)) !important; }
        }
        /* pwaBanner usa bottom-4 de Tailwind (1rem); en mobile se suma la barra. */
        @media (max-width: 639.98px) {
            #pwaBanner { bottom: calc(1rem + var(--bottom-nav-h)) !important; }
        }
        :root {
            --elev-surface: #111115;
            --elev-surface-2: #1c1c26;   /* tarjetas anidadas / inputs dentro de un modal */
            --elev-border:  rgba(255,255,255,0.12);
            /* Banner de aviso "por cerrar" (ámbar). */
            --warn-surface: linear-gradient(to right, rgba(245,158,11,0.12), rgba(245,158,11,0.03));
            --warn-border:  rgba(245,158,11,0.28);
            --warn-icon-bg: rgba(245,158,11,0.15);
            --warn-accent:  #fbbf24;
            /* Splash de carga (tema oscuro por defecto). */
            --splash-bg:       #0a0a0c;
            --splash-ring:     rgba(255,255,255,0.10);
            --splash-glow:     rgba(255,255,255,0.14);
            --splash-track:    rgba(255,255,255,0.13);
            --splash-sweep:    rgba(255,255,255,0.85);
            --splash-name:     rgba(255,255,255,0.55);
            --splash-logo-sh:  rgba(0,0,0,0.45);

            /* ── Colores de los estados de cita ──────────────────────────
               Estos son los del panel del profesional: Confirmada azul y
               Completada verde, la convención a la que está acostumbrado
               (el panel admin usa la inversa, a propósito).

               Si el local elige una paleta en Configuración → Colores de la
               agenda, `aplicarColoresAgenda()` las pisa con los hex que dejó
               guardados el panel. Mientras siga en la clásica, nadie ve un
               cambio: los valores de acá SON los de siempre. */
            --st-confirmada:      #6CABDD;
            --st-completada:      #10b981;
            --st-pendiente:       #eab308;
            --st-cancelada:       #ef4444;
            /* La cancelada se dibuja siempre translúcida: la tarjeta ya va en
               opacity-40, un borde sólido la haría gritar más que las vivas. */
            --st-cancelada-suave: rgba(239,68,68,0.3);
            --st-noasistio:       #f43f5e;
            /* El cliente LLEGÓ y está (o va a estar) en la silla. No es un
               estado de la cita —es checkedInAt encima de Confirmada— pero
               pide su propio color: violeta, el único matiz que no usa ningún
               estado, para que "está aquí" no se confunda ni con la promesa
               (azul) ni con la plata (verde). Pedido El 10, 04-09-2026. */
            --st-llegada:         #8b5cf6;
        }

        /* ── Splash de carga · estilo iOS ─────────────────────────────────
           Logo del local respirando sobre un glow ambiental + barra shimmer
           delgada. Theme-aware: el <html> ya trae light-mode por el anti-FOUC,
           así que arranca en el tema real.
           Rediseño 04-10: el logo va en CÍRCULO, como en el login y en el
           encabezado (antes cuadrado redondeado: los logos redondos quedaban
           como un círculo dentro de un cuadrado), y los logos ANCHOS se ven
           enteros en vez de recortados (Punto Pilates se leía "untoPila"). */
        #loadingOverlay {
            background: var(--splash-bg);
            transition: opacity .25s ease;
        }
        /* Salida con desvanecido. `.hidden` era display:none y la transición
           nunca corría: corte seco al esqueleto. Escondido no se puede tocar
           y las animaciones se pausan. */
        #loadingOverlay.hidden {
            display: flex;
            opacity: 0; visibility: hidden; pointer-events: none;
            transition: opacity .25s ease, visibility 0s linear .25s;
        }
        #loadingOverlay.hidden * { animation-play-state: paused !important; }
        .splash-glow {
            position: absolute;
            width: 320px; height: 320px; border-radius: 50%;
            background: radial-gradient(circle, var(--splash-glow), transparent 68%);
            filter: blur(44px);
            animation: splashGlow 3s ease-in-out infinite;
            pointer-events: none;
        }
        @keyframes splashGlow {
            0%, 100% { transform: scale(1);    opacity: 0.5; }
            50%      { transform: scale(1.18); opacity: 0.9; }
        }
        .splash-logo {
            position: relative;
            width: 96px; height: 96px; border-radius: 50%; object-fit: cover;
            box-shadow: 0 12px 42px var(--splash-logo-sh), 0 0 0 1px var(--splash-ring);
            animation: splashBreathe 2.4s ease-in-out infinite;
        }
        /* Mismo criterio que .login-logo--ancho: más de 1,25:1 va entero. */
        .splash-logo.splash-logo--ancho {
            width: auto; height: 64px; max-width: 210px;
            border-radius: 0; object-fit: contain;
            box-shadow: none; filter: drop-shadow(0 6px 18px var(--splash-logo-sh));
        }
        @keyframes splashBreathe {
            0%, 100% { transform: scale(1);     }
            50%      { transform: scale(1.045); }
        }
        /* "Agenda": dice qué se está abriendo. Antes era el nombre del local,
           que en la mayoría ya viene escrito en el logo (STIVEN BARBER dos
           veces). El nombre vuelve solo si el local no tiene logo propio. */
        .splash-name {
            position: relative;
            margin-top: 1.25rem;
            font-size: 10px; font-weight: 700; letter-spacing: 0.28em;
            text-transform: uppercase; color: var(--splash-name);
            /* Alto reservado: el logo no salta. */
            line-height: 16px; min-height: 16px;
        }
        /* Aviso de carga lenta, Syna y Reintentar: flotan bajo la barra (que
           termina ~80px bajo el centro) para no correr el logo al aparecer. */
        .splash-extra {
            position: absolute; left: 0; right: 0; top: calc(50% + 100px);
            display: flex; flex-direction: column; align-items: center;
            padding: 0 24px; text-align: center;
        }
        .splash-syna {
            height: 72px; width: auto; margin-bottom: 0.6rem;
            animation: splashSyna 2.6s ease-in-out infinite;
        }
        @keyframes splashSyna {
            0%, 100% { transform: translateY(0);    }
            50%      { transform: translateY(-4px); }
        }
        .splash-lento {
            margin: 0;
            font-size: 12px; color: var(--splash-name);
        }
        .splash-reintentar {
            margin-top: 0.9rem;
            padding: 8px 18px; border-radius: 9999px;
            font-size: 12px; font-weight: 700; letter-spacing: 0.04em;
            color: var(--splash-sweep); background: transparent;
            border: 1px solid var(--splash-ring); cursor: pointer;
        }
        .splash-bar {
            position: relative;
            margin-top: 1.4rem;
            width: 120px; height: 3px; border-radius: 99px;
            background: var(--splash-track); overflow: hidden;
        }
        /* El brillo pasaba la mitad del ciclo fuera de la barra y casi no se
           veía: ahora recorre justo de borde a borde. */
        .splash-bar-fill {
            width: 45%; height: 100%; border-radius: 99px;
            background: linear-gradient(90deg, transparent, var(--splash-sweep) 35%, var(--splash-sweep) 65%, transparent);
            animation: splashSweep 1.3s ease-in-out infinite;
        }
        @keyframes splashSweep {
            0%   { transform: translateX(-100%); }
            100% { transform: translateX(222%);  }
        }
        /* Firma de la plataforma, abajo y discreta: el protagonista es el local. */
        .splash-firma {
            position: absolute; left: 0; right: 0;
            bottom: calc(env(safe-area-inset-bottom, 0px) + 26px);
            display: flex; align-items: center; justify-content: center; gap: 6px;
            margin: 0; font-size: 10.5px; letter-spacing: 0.04em;
            color: var(--splash-name); opacity: 0.75;
        }
        .splash-firma img { width: 14px; height: 14px; border-radius: 9999px; }
        .splash-firma b { font-weight: 700; }
        @media (prefers-reduced-motion: reduce) {
            .splash-glow, .splash-logo, .splash-syna { animation: none; }
            .splash-bar-fill { animation-duration: 2.4s; }
        }

        * {
            -webkit-tap-highlight-color: transparent;
        }

        button, a, select, input[type="button"], input[type="submit"] {
            -webkit-user-select: none;
            user-select: none;
        }

        @media (max-width: 767px) {
            input, select, textarea {
                font-size: 16px !important;
            }
        }

        body {
            background-color: #050505;
            color: #f8fafc;
            font-family: 'Inter', sans-serif;
            -webkit-tap-highlight-color: transparent;
        }

        .glass-card {
            background: rgba(17, 17, 21, 0.8);
            backdrop-filter: blur(12px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }

        .text-neon {
            color: #ffffff;
            text-shadow: 0 0 10px rgba(255, 255, 255, 0.4);
        }

        .border-neon {
            border-color: #ffffff;
            box-shadow: 0 0 15px rgba(255, 255, 255, 0.1);
        }

        .no-scrollbar::-webkit-scrollbar {
            display: none;
        }
        .no-scrollbar {
            -ms-overflow-style: none;
            scrollbar-width: none;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .animate-fade-in {
            animation: fadeIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
        }

        @keyframes fadeInUp {
            from { opacity: 0; transform: translateY(18px) scale(0.98); }
            to { opacity: 1; transform: translateY(0) scale(1); }
        }

        /* ── Fundido suave al mostrar una vista (sin salto vertical) ── */
        @keyframes viewIn { from { opacity: 0; } to { opacity: 1; } }
        .view-in { animation: viewIn .18s ease; }

        /* ── SKELETONS: shimmer sutil hasta que llegue Firestore ── */
        @keyframes skelShimmer {
            0%   { background-position: 200% 0; }
            100% { background-position: -200% 0; }
        }
        .skel-card {
            background: linear-gradient(90deg,
                rgba(255,255,255,0.03) 25%,
                rgba(255,255,255,0.07) 50%,
                rgba(255,255,255,0.03) 75%);
            background-size: 200% 100%;
            animation: skelShimmer 1.6s linear infinite;
            border: 1px solid rgba(255,255,255,0.06);
            border-left: 4px solid rgba(255,255,255,0.12);
        }
        .skel-line {
            background: rgba(255,255,255,0.08);
            border-radius: 4px;
        }
        html.light-mode .skel-card {
            background: linear-gradient(90deg,
                rgba(15,23,42,0.04) 25%,
                rgba(15,23,42,0.09) 50%,
                rgba(15,23,42,0.04) 75%);
            background-size: 200% 100%;
            border-color: rgba(15,23,42,0.08);
            border-left-color: rgba(15,23,42,0.16);
        }
        html.light-mode .skel-line { background: rgba(15,23,42,0.1); }

        /* ── PERFIL modal: esquinas + border responsivos ── */
        /* Mobile default: bottom sheet, esquinas SUPERIORES redondeadas,
           borde inferior fuera de vista (pegado al viewport). */
        /* Desktop: card centrada, 4 esquinas redondeadas. */
        @media (min-width: 640px) {
            #perfilModal {
                border-radius: 24px !important;
                box-shadow: 0 20px 60px rgba(0,0,0,0.55);
            }
        }
        /* Safari/WebKit dibuja su propio triángulo en <summary> pese a
           list-style:none. Lo ocultamos: usamos nuestro caret. */
        #perfilDatos > summary::-webkit-details-marker { display: none; }

        /* Resalte breve al saltar desde el chip "Sigue" hacia la cita. */
        @keyframes citaFlash {
            0%, 100% { box-shadow: 0 0 0 0 rgba(201,168,76,0); }
            30%      { box-shadow: 0 0 0 3px rgba(201,168,76,0.55); }
        }
        .cita-flash { animation: citaFlash 1.7s cubic-bezier(0.22,1,0.36,1); }

        /* Header compacto al scrollear: recupera alto sin saltos bruscos.
           Ojo: más abajo hay `@media(max-width:639px){header.sticky{padding:.85rem !important}}`,
           así que necesitamos misma arma (!important) y más especificidad
           (header.sticky.header-compact) para ganarle.

           Todo padding-top del header suma env(safe-area-inset-top): con la
           agenda instalada en el iPhone (black-translucent + viewport-fit=cover)
           la página se dibuja DEBAJO del reloj y la batería, y sin ese margen
           los botones de la derecha (panel, avisos, historial) quedaban tapados
           por la barra de estado e intocables (Jhoseth, 08-10-2026). En el
           navegador normal el inset vale 0 y nada cambia. */
        header { transition: padding .18s ease; }
        @media (min-width: 640px) {
            header.sticky { padding-top: calc(env(safe-area-inset-top, 0px) + 1.25rem); }
        }
        header.sticky.header-compact {
            padding-top: calc(env(safe-area-inset-top, 0px) + .5rem) !important;
            padding-bottom: .5rem !important;
        }
        @media (min-width: 640px) {
            header.sticky.header-compact {
                padding-top: calc(env(safe-area-inset-top, 0px) + .75rem) !important;
                padding-bottom: .75rem !important;
            }
        }

        /* Barra de densidad de la tira de días: cuán lleno está cada día. */
        .dens-bar {
            width: 20px; height: 3px; border-radius: 999px;
            background: rgba(255,255,255,0.12); overflow: hidden;
        }
        .dens-fill { height: 100%; border-radius: 999px; transition: width .25s ease; }
        /* En el chip seleccionado (fondo claro) el track debe verse. */
        .dens-bar.on-light { background: rgba(0,0,0,0.15); }

        /* ── Transición direccional al cambiar de día ── */
        @keyframes dayInNext { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes dayInPrev { from { opacity: 0; transform: translateX(-26px); } to { opacity: 1; transform: translateX(0); } }
        .anim-day-next { animation: dayInNext .3s cubic-bezier(0.22, 1, 0.36, 1); }
        .anim-day-prev { animation: dayInPrev .3s cubic-bezier(0.22, 1, 0.36, 1); }

        /* ── Touch: respuesta inmediata en móvil (mata el delay de 300ms) ── */
        button, a, .cita-card, [onclick] { touch-action: manipulation; }

        /* Tarjetas de cita: feedback de presión snappy */
        .cita-card {
            -webkit-tap-highlight-color: transparent;
            transition: transform .13s cubic-bezier(0.16,1,0.3,1), background-color .2s ease, box-shadow .2s ease;
        }
        .cita-card:active {
            transform: scale(0.975);
            box-shadow: 0 6px 22px rgba(0,0,0,0.35);
        }
        /* El handle del bottom sheet no debe scrollear la página al arrastrar */
        #citaSheetHandle { touch-action: none; }

        /* ── Live Indicator & Highlight ── */
        @keyframes livePulse {
            0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }
            70% { transform: scale(1); box-shadow: 0 0 0 4px rgba(16, 185, 129, 0); }
            100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
        }
        .live-dot {
            width: 8px; height: 8px;
            background-color: #10b981;
            border-radius: 50%;
            animation: livePulse 2s infinite;
        }

        @keyframes newCitaGlow {
            0%, 100% { border-color: rgba(16, 185, 129, 0.5); box-shadow: 0 0 10px rgba(16,185,129,0.2); }
            50% { border-color: #10b981; box-shadow: 0 0 20px rgba(16,185,129,0.6); }
        }
        .cita-nueva-highlight {
            animation: newCitaGlow 1.5s ease-in-out infinite;
            border-left: 4px solid #10b981 !important;
        }

        /* ═══════════════════════════════════════════════════════════════════
           MODO CLARO — Alto contraste para lectura bajo luz directa del sol.
           Namespace: html.light-mode (aplicado antes del primer paint por el
           script anti-FOUC del <head>). El toggle vive en el header (#theme-toggle).

           Estrategia: overrides con selectores específicos + !important sobre
           las clases Tailwind ya presentes en el markup (bg-white/5, text-white,
           bg-brand-bg, etc.), sin tocar JS ni recompilar Tailwind.
           ═══════════════════════════════════════════════════════════════════ */

        /* Transiciones suaves entre modos — solo en los envoltorios principales
           para no chocar con animaciones existentes (cita-nueva-highlight, live-dot). */
        html.light-mode body,
        html.light-mode header,
        html.light-mode .cita-card,
        html.light-mode [id="daySelectorContainer"] button,
        html.light-mode .glass-card,
        html.light-mode #dailyStatsDashboard {
            transition: background-color .2s ease, border-color .2s ease, color .2s ease !important;
        }

        /* ── Fondo general ────────────────────────────────────────────────── */
        html.light-mode body {
            background-color: #f8fafc !important;
            color: #0f172a !important;
        }

        /* ── Header sticky ────────────────────────────────────────────────── */
        html.light-mode header.sticky {
            background: rgba(255, 255, 255, 0.92) !important;
            border-bottom-color: #e2e8f0 !important;
        }

        /* ── Superficies translúcidas → blanco puro con borde ─────────────── */
        html.light-mode .bg-white\/5,
        html.light-mode .bg-white\/\[0\.03\],
        html.light-mode .bg-white\/\[0\.02\] {
            background-color: #ffffff !important;
        }
        html.light-mode .bg-white\/10,
        html.light-mode .bg-white\/15,
        html.light-mode .bg-white\/20 {
            background-color: #f1f5f9 !important;
        }

        /* Brand bg + su versión con opacidad → tela suave */
        html.light-mode .bg-brand-bg,
        html.light-mode .bg-brand-bg\/90,
        html.light-mode .bg-brand-bg\/80 {
            background-color: #f8fafc !important;
        }

        /* ── Superficies oscuras que quedaban negras en modo claro ──────────
           Auditoría 2026-07. Solo lo que aparece SOBRE la app clara. NO se
           tocan el splash de carga (#loadingOverlay) ni la pantalla de login
           (#loginOverlay): son pantallas oscuras a propósito (foto + spinner
           blanco), aclararlas rompería su texto/spinner blanco.
           Los inline se pisan por selector de atributo — un !important de
           hoja gana al inline. */

        /* Banner + modal de instalar PWA: su fondo era inline #111115. Un
           !important de hoja NO lo pisa en esta página (Tailwind CDN mete sus
           utilidades en @layer y, para !important, las capas ganan al CSS sin
           capa). Se resuelve con variable: el inline lee var(--elev-surface),
           que cambia por tema. El texto usa .text-white (ya invertido). */
        html.light-mode {
            --elev-surface: #ffffff;
            --elev-surface-2: #f1f5f9;   /* gris muy suave para lo anidado */
            --elev-border:  #e2e8f0;
            /* Ámbar suave en claro: fondo crema tenue, acento amber-700 (no el
               #fbbf24 chillón que cansaba). */
            --warn-surface: #fef3c7;
            --warn-border:  #fcd34d;
            --warn-icon-bg: #fde68a;
            --warn-accent:  #92400e;
            /* Splash en claro: tela suave, glow y barra en grafito tenue. */
            --splash-bg:      #f8fafc;
            --splash-ring:    rgba(15,23,42,0.10);
            --splash-glow:    rgba(15,23,42,0.06);
            --splash-track:   rgba(15,23,42,0.11);
            --splash-sweep:   rgba(15,23,42,0.55);
            --splash-name:    rgba(71,85,105,0.75);
            --splash-logo-sh: rgba(15,23,42,0.14);
        }

        /* Banner de error del sistema → rojo muy claro, texto oscuro legible. */
        html.light-mode #errBanner {
            background: #fef2f2 !important;
            border-color: #fecaca !important;
            color: #991b1b !important;
        }
        html.light-mode #errBanner * { color: #991b1b !important; }
        html.light-mode #errBanner .err-banner-reload {
            background: #991b1b !important;
            color: #ffffff !important;
        }
        /* Banner "conexión perdida" (rose): ya es una alerta de color; en claro
           lo dejamos sólido rose-600 para que se lea sin el tinte translúcido. */
        html.light-mode #connBanner { background: #e11d48 !important; }

        /* Fondos oscuros de tarjetas de cita ($1c1c24) → pastel azul */
        html.light-mode .bg-\[\#1c1c24\] {
            background-color: #eff6ff !important;
        }
        html.light-mode .hover\:bg-\[\#22222c\]:hover {
            background-color: #dbeafe !important;
        }

        /* Zinc oscuro (avatares en cita) → gris claro */
        html.light-mode .bg-zinc-800 { background-color: #e2e8f0 !important; }
        html.light-mode .text-zinc-400 { color: #475569 !important; }

        /* ── Bordes translúcidos → gris slate-200 sólido ──────────────────── */
        html.light-mode .border-white\/5,
        html.light-mode .border-white\/10,
        html.light-mode .border-white\/15,
        html.light-mode .border-white\/20,
        html.light-mode .border-white\/25,
        html.light-mode .border-white\/30 {
            border-color: #e2e8f0 !important;
        }

        /* ── Textos blancos → slate-900 (con jerarquía de opacidad) ───────── */
        html.light-mode .text-white { color: #0f172a !important; }
        html.light-mode .text-white\/90 { color: #0f172a !important; }
        /* /85 = precio de la cita; /55 = nombre del servicio; /45 y /35
           sueltos. No estaban mapeados → quedaban BLANCOS sobre la tarjeta
           celeste clara (invisibles). Se slotean en la misma rampa slate. */
        html.light-mode .text-white\/85 { color: #0f172a !important; }
        html.light-mode .text-white\/80 { color: #1e293b !important; }
        html.light-mode .text-white\/55 { color: #475569 !important; }
        html.light-mode .text-white\/45 { color: #64748b !important; }
        html.light-mode .text-white\/35 { color: #94a3b8 !important; }
        html.light-mode .text-white\/70 { color: #334155 !important; }
        html.light-mode .text-white\/60 { color: #475569 !important; }
        html.light-mode .text-white\/50 { color: #64748b !important; }
        html.light-mode .text-white\/40 { color: #64748b !important; }
        html.light-mode .text-white\/30 { color: #94a3b8 !important; }
        html.light-mode .text-white\/20 { color: #cbd5e1 !important; }
        html.light-mode .text-white\/10 { color: #e2e8f0 !important; }

        /* Neon (headings con brillo blanco) → slate-900 sin brillo */
        html.light-mode .text-neon {
            color: #0f172a !important;
            text-shadow: none !important;
        }
        html.light-mode .border-neon {
            border-color: #0f172a !important;
            box-shadow: none !important;
        }

        /* ── Glass card → superficie blanca con borde suave ───────────────── */
        html.light-mode .glass-card {
            background: rgba(255, 255, 255, 0.9) !important;
            border-color: #e2e8f0 !important;
            backdrop-filter: blur(12px);
        }

        /* ── Selector de días: día activo debe destacar sobre calendario blanco.
             El día activo usa bg-zinc-100 (píldora clara sobre oscuro). En modo
             claro la invertimos a píldora oscura sólida (slate-900) sobre fondo
             blanco. Sus hijos (números y punto interior) los blanqueamos. ──── */
        html.light-mode .bg-zinc-100 {
            background-color: #0f172a !important;
            box-shadow: 0 4px 12px -2px rgba(15, 23, 42, 0.25) !important;
        }
        html.light-mode .bg-zinc-100 .text-black,
        html.light-mode .bg-zinc-100 .text-zinc-500,
        html.light-mode .bg-zinc-100 .text-zinc-400 {
            color: #ffffff !important;
        }
        html.light-mode .bg-zinc-100 .bg-zinc-700 {
            background-color: #ffffff !important;
        }

        /* ── Tarjetas de cita: pastel + borde izq de color respetado ──────── */
        html.light-mode .cita-card {
            border: 1px solid #cbd5e1 !important;
            /* El borde izquierdo colorido lo pinta el JS inline y ese gana */
            color: #0f172a !important;
            box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06) !important;
        }
        html.light-mode .cita-card:active {
            box-shadow: 0 4px 14px rgba(15, 23, 42, 0.12) !important;
        }
        /* Chip del abono (06-10-2026, `_chipAbono`): en claro, colores propios.
           Las clases de Tailwind del modo oscuro quedaban grises o lavadas, y
           el rojo de "abono sin usar" es justo el que no se puede perder. */
        html.light-mode .cita-card .abono-chip-parcial { background-color: #fef3c7 !important; color: #92400e !important; box-shadow: inset 0 0 0 1px #fcd34d !important; }
        html.light-mode .cita-card .abono-chip-sinUsar { background-color: #fee2e2 !important; color: #b91c1c !important; box-shadow: inset 0 0 0 1px #fca5a5 !important; }
        html.light-mode .cita-card .abono-chip-completo { background-color: #10b981 !important; color: #ffffff !important; }
        /* El divisor vertical dentro de la tarjeta */
        html.light-mode .cita-card .bg-white\/10,
        html.light-mode .cita-card .bg-white\/5 {
            background-color: #cbd5e1 !important;
        }

        /* ── Botones de estado dentro de las tarjetas (check verde, X rojo, WA) ──
             Los fondos ya son bg-emerald-500/10 etc. — quedan bien en claro.
             Reforzamos los textos y los bordes para contraste extra. */
        html.light-mode .bg-emerald-500\/10 { background-color: #d1fae5 !important; }
        html.light-mode .bg-emerald-500\/15 { background-color: #a7f3d0 !important; }
        html.light-mode .bg-emerald-500\/20 { background-color: #6ee7b7 !important; }
        html.light-mode .border-emerald-500\/20,
        html.light-mode .border-emerald-500\/30 { border-color: #10b981 !important; }
        html.light-mode .text-emerald-400 { color: #047857 !important; }
        html.light-mode .text-emerald-300 { color: #059669 !important; }

        html.light-mode .bg-red-500\/10 { background-color: #fee2e2 !important; }
        html.light-mode .bg-red-500\/20 { background-color: #fecaca !important; }
        html.light-mode .border-red-500\/20,
        html.light-mode .border-red-500\/30 { border-color: #ef4444 !important; }
        html.light-mode .text-red-400 { color: #b91c1c !important; }

        html.light-mode .bg-yellow-500\/10 { background-color: #fef3c7 !important; }
        html.light-mode .text-yellow-400 { color: #b45309 !important; }
        html.light-mode .text-blue-400 { color: #1d4ed8 !important; }

        /* ── Botón WhatsApp del header/tarjeta: mantiene el verde marca ───── */
        html.light-mode .bg-\[\#25D366\]\/10 { background-color: #dcfce7 !important; }
        html.light-mode .bg-\[\#25D366\]\/20 { background-color: #bbf7d0 !important; }
        html.light-mode .border-\[\#25D366\]\/20,
        html.light-mode .border-\[\#25D366\]\/30 { border-color: #25D366 !important; }

        /* ── Brand accent (dorado): oscurece ligeramente para lectura sobre blanco ── */
        html.light-mode .text-brand-accent { color: #a17d3a !important; }
        html.light-mode .bg-brand-accent { background-color: #a17d3a !important; }
        html.light-mode .border-brand-accent { border-color: #a17d3a !important; }

        /* ── Sombras neon/glow oscuras: quitarles el brillo blanco pesado ── */
        html.light-mode .shadow-\[0_0_15px_rgba\(255\,255\,255\,0\.2\)\],
        html.light-mode .shadow-\[0_0_10px_rgba\(255\,255\,255\,0\.4\)\] {
            box-shadow: 0 1px 3px rgba(15, 23, 42, 0.1) !important;
        }

        /* ── Selects con fondo #111 forzado en las opciones (Chrome android) ── */
        html.light-mode select option { background: #ffffff !important; color: #0f172a !important; }

        /* ── Botón #theme-toggle: propia iluminación según modo ───────────── */
        html.light-mode #theme-toggle {
            border-color: #e2e8f0 !important;
            background-color: #ffffff !important;
        }
        html.light-mode #theme-toggle:hover {
            background-color: #f1f5f9 !important;
        }
        html.light-mode #themeIcon {
            color: #0f172a !important;
        }

        /* ═══════════════════════════════════════════════════════════════════
           AJUSTES DE CONTRASTE (modo claro) — segunda pasada
           Zonas donde el mapeo genérico dejaba texto/íconos casi invisibles
           bajo luz directa (horas, "Espacio disponible", íconos de acción,
           KPIs, píldoras, banner de instalación). Van al final adrede: por
           orden en cascada ganan sobre los mapeos globales anteriores.
           ═══════════════════════════════════════════════════════════════════ */

        /* Fracciones de opacidad usadas por buildFreeSlot que no existían
           en el mapeo global (text-white/25 en la hora, text-white/15 en el
           candado). Ambas van a slate oscuro con peso 600 para leerse a
           pleno sol. */
        html.light-mode .text-white\/25 { color: #1e293b !important; }
        html.light-mode .text-white\/15 { color: #334155 !important; }

        /* Bordes horizontales de la grilla (separan cada franja de 15/30 min).
           border-white/[0.06] y su hover eran translúcidos → se perdían
           encima del fondo blanco. */
        html.light-mode .border-white\/\[0\.06\] { border-color: #e2e8f0 !important; }
        html.light-mode .hover\:border-white\/10:hover { border-color: #cbd5e1 !important; }
        /* Divisor vertical del free slot */
        html.light-mode .bg-white\/\[0\.06\] { background-color: #cbd5e1 !important; }

        /* ── Grilla horaria de la vista Día ─────────────────────────────
           Horas (10:00, 10:15…) a la izquierda, "Espacio disponible"
           al centro, íconos de acción (+ / candado) a la derecha. */
        html.light-mode #morningSlots .text-white\/25,
        html.light-mode #afternoonSlots .text-white\/25 {
            color: #1e293b !important;    /* slate-800: hora legible */
            font-weight: 600 !important;
        }
        html.light-mode #morningSlots .text-white\/20,
        html.light-mode #afternoonSlots .text-white\/20 {
            color: #475569 !important;    /* slate-600: "Espacio disponible" */
        }
        html.light-mode #morningSlots .text-white\/15,
        html.light-mode #afternoonSlots .text-white\/15 {
            color: #334155 !important;    /* slate-700: ícono candado */
        }
        html.light-mode #morningSlots .text-white\/40,
        html.light-mode #afternoonSlots .text-white\/40 {
            color: #334155 !important;    /* slate-700: ícono + (visible al hover) */
        }
        /* Al pasar el cursor por el free slot el texto oscurece más aún
           (contra-intuitivo del oscuro, pero coherente con la lectura). */
        html.light-mode .group:hover .group-hover\:text-white\/40 { color: #0f172a !important; }

        /* Encabezados "Mañana" / "Tarde" y estado vacío */
        html.light-mode #morningLabel,
        html.light-mode #afternoonLabel { color: #334155 !important; }
        html.light-mode #emptyAgenda .text-white\/20,
        html.light-mode #emptyAgenda .text-white\/40 { color: #64748b !important; }

        /* ── Píldoras 15'/30'/45'/1h y toggle Día/Semana ────────────────
           Los estados activo/inactivo los pinta el JS con style inline
           SIN !important (ver _updateIntervalUI/_updateViewToggleUI, ya
           refactorizados para ser theme-aware). Estos !important son la
           red de seguridad del primer paint. */
        html.light-mode #intervalSelectorWrap > div,
        html.light-mode div:has(> #viewBtnDia) {
            background: #f1f5f9 !important;   /* slate-100 */
            border: 1px solid #cbd5e1 !important;
        }
        html.light-mode #intervalSelectorWrap > span { color: #334155 !important; }
        html.light-mode .int-btn,
        html.light-mode #viewBtnDia,
        html.light-mode #viewBtnSemana { color: #334155 !important; }

        /* El estado activo lo marca JS con .agenda-pill-active. Esta regla debe
           ser mas especifica que la red de seguridad anterior: de lo contrario
           el !important del texto inactivo tambien se aplica al boton activo y
           deja texto slate sobre fondo slate. */
        html.light-mode .int-btn.agenda-pill-active,
        html.light-mode #viewBtnDia.agenda-pill-active,
        html.light-mode #viewBtnSemana.agenda-pill-active {
            background: #0f172a !important;
            color: #ffffff !important;
            box-shadow: 0 2px 6px rgba(15, 23, 42, 0.20);
        }
        html.light-mode .int-btn.agenda-pill-active i,
        html.light-mode #viewBtnDia.agenda-pill-active i,
        html.light-mode #viewBtnSemana.agenda-pill-active i {
            color: #ffffff !important;
        }

        /* ── Mini-dashboard de KPIs (Completadas / Pendientes / Proyección)
           Tarjeta blanca sólida con borde marcado y textos en slate-900. */
        html.light-mode #dailyStatsDashboard {
            background: #ffffff !important;
            border-color: #cbd5e1 !important;
            box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06) !important;
        }
        html.light-mode #dailyStatsDashboard .border-white\/10 { border-color: #cbd5e1 !important; }
        html.light-mode #dailyStatsDashboard #statCompletadas,
        html.light-mode #dailyStatsDashboard #statPendientes { color: #0f172a !important; }
        html.light-mode #dailyStatsDashboard .text-white\/50 {
            color: #334155 !important;
            font-weight: 700 !important;
        }
        /* Etiqueta "Proyección" venía en text-brand-accent/50 (dorado casi
           transparente): forzamos slate-700 como sus hermanas. */
        html.light-mode #dailyStatsDashboard .text-brand-accent\/50 {
            color: #334155 !important;
            font-weight: 700 !important;
        }
        /* text-brand-accent CON opacidad (/50, /60, /80) es una clase que
           Tailwind no genera (brand-accent no lleva <alpha-value>): el texto
           heredaba BLANCO, invisible en claro (ej. "Hoy/Semana/Mes" del modal
           de proyección). Se fija al dorado legible. El override del dashboard
           de arriba, más específico por el id, sigue mandando ahí. */
        html.light-mode .text-brand-accent\/80,
        html.light-mode .text-brand-accent\/60,
        html.light-mode .text-brand-accent\/50 { color: #a17d3a !important; }

        /* ── Banner "Instalar como Aplicación" ─────────────────────────
           Fondo/gradiente inline en oro semi-transparente eran casi
           invisibles sobre blanco. Lo pasamos a amber-50 con borde
           amber-300 y refuerzo del título. */
        html.light-mode #pwaBigInstallCard {
            background: rgba(254, 243, 199, 0.6) !important;
            border: 1px solid #fcd34d !important;
            box-shadow: none !important;
        }
        html.light-mode #pwaBigInstallCard h3 {
            color: #0f172a !important;
            font-weight: 800 !important;
        }
        html.light-mode #pwaBigInstallCard .text-white\/60 { color: #475569 !important; }
        html.light-mode #pwaBigInstallCard button[aria-label="Descartar"] {
            color: #92400e !important;
            background: rgba(180, 83, 9, 0.08) !important;
        }

        /* ── Historial de actualizaciones ──────────────────────────────
           Registro interno, neutro y editorial. El verde solo comunica
           estado; no hay degradados, brillos ni una tarjeta protagonista. */
        #agendaNewsView {
            min-height: min(68dvh, 620px);
            scroll-margin-top: 88px;
        }
        #agendaNewsPanel {
            overflow: hidden;
            background: rgba(255,255,255,0.025);
            border: 1px solid rgba(255,255,255,0.09);
        }
        .agenda-updates-icon {
            background: rgba(52,211,153,0.08);
            border: 1px solid rgba(52,211,153,0.18);
            color: #34d399;
        }
        .agenda-update-row {
            position: relative;
            padding: 16px 16px 16px 42px;
            border-top: 1px solid rgba(255,255,255,0.07);
        }
        .agenda-update-row::before {
            content: '';
            position: absolute;
            left: 20px;
            top: 21px;
            width: 7px;
            height: 7px;
            border-radius: 999px;
            background: rgba(255,255,255,0.22);
        }
        .agenda-update-row.is-current::before { background: #34d399; }
        .agenda-update-status {
            padding: 3px 7px;
            border-radius: 999px;
            background: rgba(255,255,255,0.055);
            border: 1px solid rgba(255,255,255,0.08);
            color: rgba(255,255,255,0.55);
        }
        .agenda-update-row.is-current .agenda-update-status {
            background: rgba(52,211,153,0.08);
            border-color: rgba(52,211,153,0.2);
            color: #6ee7b7;
        }
        html.light-mode #agendaNewsPanel {
            background: #ffffff;
            border-color: #e2e8f0;
        }
        html.light-mode .agenda-updates-icon {
            background: #ecfdf5;
            border-color: #a7f3d0;
            color: #047857;
        }
        html.light-mode .agenda-update-row { border-top-color: #e2e8f0; }
        html.light-mode .agenda-update-row::before { background: #cbd5e1; }
        html.light-mode .agenda-update-row.is-current::before { background: #059669; }
        html.light-mode .agenda-update-status {
            background: #f8fafc;
            border-color: #e2e8f0;
            color: #64748b;
        }
        html.light-mode .agenda-update-row.is-current .agenda-update-status {
            background: #ecfdf5;
            border-color: #a7f3d0;
            color: #047857;
        }

        #agendaNewsNotice {
            position: fixed;
            top: calc(env(safe-area-inset-top, 0px) + 72px);
            left: 50%;
            z-index: 32000;
            width: min(calc(100vw - 24px), 390px);
            transform: translateX(-50%) translateY(-18px);
            opacity: 0;
            pointer-events: none;
            transition: transform .36s cubic-bezier(0.16,1,0.3,1), opacity .25s ease;
        }
        #agendaNewsNotice.is-visible {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
            pointer-events: auto;
        }
        html.light-mode #agendaNewsNotice > button {
            background: rgba(255,255,255,0.97) !important;
            border-color: #d1d5db !important;
            box-shadow: 0 10px 26px rgba(15,23,42,0.12) !important;
        }
        html.light-mode #agendaNewsNotice .agenda-news-notice-title { color: #0f172a !important; }
        html.light-mode #agendaNewsNotice .agenda-news-notice-copy { color: #475569 !important; }

        /* Novedades es una vista real de navegación, no una tarjeta mezclada
           con los avisos operativos. Se aplica también en escritorio para que
           la cabecera de semana no asome cortada al final del historial. */
        .agenda-primary-column.agenda-news-mode > :not(#agendaNewsView) {
            display: none !important;
        }
        .agenda-primary-column.agenda-news-mode #agendaNewsView {
            display: block !important;
        }

        /* Los horarios y acciones son informacion operativa, no decoracion.
           En oscuro las opacidades originales (20-35 %) parecian estados
           deshabilitados y dificultaban leer la agenda de un vistazo. */
        html:not(.light-mode) #morningLabel,
        html:not(.light-mode) #afternoonLabel { color: rgba(255,255,255,0.68) !important; }
        html:not(.light-mode) #morningSlots .text-white\/25,
        html:not(.light-mode) #afternoonSlots .text-white\/25 { color: rgba(255,255,255,0.72) !important; }
        html:not(.light-mode) #morningSlots .text-white\/20,
        html:not(.light-mode) #afternoonSlots .text-white\/20 { color: rgba(255,255,255,0.62) !important; }
        html:not(.light-mode) #morningSlots .text-white\/15,
        html:not(.light-mode) #afternoonSlots .text-white\/15 { color: rgba(255,255,255,0.52) !important; }
        html:not(.light-mode) #morningSlots .text-white\/40,
        html:not(.light-mode) #afternoonSlots .text-white\/40 { color: rgba(255,255,255,0.72) !important; }
        .agenda-ext-hours-btn { font-size: 11px !important; }
        html:not(.light-mode) .agenda-ext-hours-btn {
            color: rgba(255,255,255,0.68) !important;
            border-color: rgba(255,255,255,0.28) !important;
        }
        html.light-mode .agenda-ext-hours-btn {
            color: #475569 !important;
            border-color: #cbd5e1 !important;
            background: rgba(255,255,255,0.65);
        }

        /* En desktop la columna tiene alto fijo y scroll propio. Evitamos que
           flex comprima el banner PWA y los KPI antes de habilitar el scroll. */
        @media (min-width: 1024px) {
            #mainApp > .agenda-primary-column > * { flex-shrink: 0; }
        }

        /* El FAB ya no cubre el control + de los espacios libres en movil: la
           fila reserva un pequeno carril derecho justo donde flota el boton. */
        @media (max-width: 1023px) {
            .agenda-free-slot, .agenda-tramo-btn { padding-right: 5rem !important; }
            #fabNuevaCita {
                min-width: 3.25rem !important;
                height: 3.25rem !important;
                right: 1rem !important;
            }
        }

        /* ═══════════════════════════════════════════════════════════════════
           FIXES POST-QA — tercera pasada tras QA en mobile.
           Cuatro áreas: header opaco + aire, franjas oscuras vista semana,
           relieve en estados vacíos, y sticky del selector de días.
           ═══════════════════════════════════════════════════════════════════ */

        /* (1) Header 100% opaco: el 0.92 dejaba pasar el contenido detrás
              como un fantasma al scrollear. Sombra sutil en vez de blur. */
        html.light-mode header.sticky {
            background: #ffffff !important;
            box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
        }
        /* Aire extra bajo el header — el pt-8 dejaba el toggle día/semana
           casi pegado al borde inferior del header en mobile. */
        /* `hidden lg:grid` no alcanza para esconder la app: a partir de 1024px
           `lg:grid` le gana a `hidden` por orden de cascada (es el patron normal
           de "solo escritorio"). Resultado: antes de autenticar, el grid ya venia
           renderizado debajo del login, y al cerrar sesion se quedaba ahi.
           Esta clase si gana, y es la que gobierna el estado de sesion. */
        .app-oculta { display: none !important; }   /* generico: mainApp Y bottomNav */

        html.light-mode #mainApp {
            padding-top: 1.5rem !important;
        }

        /* (2) Vista SEMANA — antes: attribute-selectors [style*="..."] pisando
              los cssText inline emitidos por renderWeekView. Ahora ese render
              lee document.documentElement.classList y pinta con `pal.*`, por
              lo que este bloque ya NO es necesario. Se conservan solo los
              overrides que apuntan al HTML estático (modales, contenedores
              decorativos) que sí siguen siendo inline en el markup. */
        html.light-mode [style*="rgba(255,255,255,0.02)"],
        html.light-mode [style*="rgba(255,255,255,0.04)"] {
            background: #ffffff !important;
        }
        html.light-mode [style*="1px solid rgba(255,255,255,0.05)"],
        html.light-mode [style*="1px solid rgba(255,255,255,0.1)"],
        html.light-mode [style*="1px solid rgba(255,255,255,0.12)"] {
            border-color: #e2e8f0 !important;
        }

        /* (3) Estados vacíos con relieve — evita el "flotar en el vacío"
              cuando la tarjeta queda sobre el fondo #f8fafc del body. */
        html.light-mode #emptyAgenda {
            background: #ffffff !important;
            border: 1px solid #e2e8f0 !important;
            border-radius: 0.75rem;
            padding: 1.75rem 1.5rem !important;
            box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
            margin-top: 0.5rem;
        }
        html.light-mode #emptyAgenda i { color: #94a3b8 !important; }
        html.light-mode #emptyAgenda p { color: #475569 !important; }

        html.light-mode #desktopDetailView {
            background: #ffffff !important;
            border: 1px solid #e2e8f0 !important;
            box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
        }
        html.light-mode #desktopEmptyState,
        html.light-mode #desktopEmptyState i,
        html.light-mode #desktopEmptyState p {
            color: #64748b !important;
        }

        /* Cards internas del carrusel "Últimas reservas recibidas" */
        html.light-mode #latestReservationsContainer > div {
            background: #ffffff !important;
            border-color: #e2e8f0 !important;
        }

        /* ═══════════════════════════════════════════════════════════════════
           CUARTA PASADA — QA final: modales sincronizados + cabeceras y
           columnas de tiempo garantizadas en claro.
           HALLAZGO CLAVE: el navegador NORMALIZA los valores hex/rgba del
           atributo style al aplicarlos (#141418 → rgb(20, 20, 24)). El selector
           [style*="..."] compara contra la versión normalizada del DOM. Por eso
           las pasadas anteriores fallaban en algunos móviles: solo cubrían la
           forma hex original. Aquí duplicamos con las variantes rgb() esperadas.
           ═══════════════════════════════════════════════════════════════════ */

        /* ── (A) Modales — backdrop del overlay ──────────────────────────
           Bajamos el negro 70% (rgba(0,0,0,0.7)) del backdrop a un slate 40%
           para no "quemar" la UI clara con una máscara casi opaca al abrir. */
        /* ── Modal Nueva Cita: optimizado para teléfonos ──
           La card nunca supera el viewport: el cuerpo de campos scrollea y el
           botón Guardar queda SIEMPRE visible (antes en pantallas chicas el
           botón quedaba cortado bajo el borde). En móvil queda centrado en el
           espacio visible, respetando los bordes seguros y el teclado. */
        #agendarModal > div { max-height: 92vh; max-height: 92dvh; }
        @media (max-width: 640px) {
            #agendarModal { align-items: center; padding: 12px; }
            #agendarModal > div {
                max-width: none;
                border-radius: 1.5rem;
                padding: 1.25rem 1.25rem calc(0.75rem + env(safe-area-inset-bottom));
            }
            /* iOS hace auto-zoom al enfocar inputs con fuente <16px — se evita
               subiendo la fuente SOLO dentro de este modal en móvil. */
            #agendarModal input, #agendarModal select { font-size: 16px !important; }
        }

        html.light-mode #freeSlotModal,
        html.light-mode #agendarModal,
        html.light-mode #editCitaOverlay,
        html.light-mode #calendarModal {
            background: rgba(15, 23, 42, 0.4) !important;
        }

        /* Contenedor interior del modal (div hijo con style inline #0d0d10 →
           rgb(13, 13, 16)). Cubrimos ambas notaciones más el fallback por hijo. */
        html.light-mode [style*="background:var(--elev-surface)"],
        html.light-mode [style*="background:var(--elev-surface)"],
        html.light-mode [style*="background:rgb(13, 13, 16)"],
        html.light-mode [style*="background:rgb(13,13,16)"],
        html.light-mode #freeSlotModal > div,
        html.light-mode #agendarModal > div,
        html.light-mode #editCitaOverlay > #editCitaSheet {
            background: #ffffff !important;
            border: 1px solid #e2e8f0 !important;
            box-shadow: 0 25px 50px -12px rgba(15, 23, 42, 0.25) !important;
        }

        /* Títulos de los modales ("Opciones para las XX:XX" / "Nueva Cita…") */
        html.light-mode #freeSlotModal h3,
        html.light-mode #agendarModal h3,
        html.light-mode #editCitaOverlay h3 {
            color: #0f172a !important;
            font-weight: 800 !important;
        }

        /* La hora destacada (span text-brand-accent inline) pasa a emerald-700
           que ES legible sobre blanco — el dorado queda muy débil. */
        html.light-mode #freeSlotTimeLabel,
        html.light-mode #agendarHoraDisplay {
            color: #047857 !important;
            font-weight: 800 !important;
        }
        html.light-mode #editCitaEyebrow { color: #64748b !important; }

        /* Botón "Bloquear Espacio Rápido" del freeSlotModal — era
           bg-white/5 border-white/10 text-white → superficie clara. */
        html.light-mode #freeSlotModal button[onclick*="accionBloquearSlot"] {
            background: #f8fafc !important;
            border: 1px solid #cbd5e1 !important;
            color: #0f172a !important;
        }
        html.light-mode #freeSlotModal button[onclick*="accionBloquearSlot"]:hover {
            background: #f1f5f9 !important;
        }
        /* Botón "Cancelar" del freeSlotModal (text-white/40) */
        html.light-mode #freeSlotModal button[onclick*="cerrarOpcionesSlotLibre"] {
            color: #64748b !important;
        }

        /* Labels de campos del formulario (text-white/40) */
        html.light-mode #agendarModal label,
        html.light-mode #editCitaOverlay label {
            color: #475569 !important;
        }

        /* Inputs y selects con style inline rgba(255,255,255,0.05) —
           superficie suave + borde sólido + texto oscuro + focus reforzado. */
        html.light-mode #agendarModal input,
        html.light-mode #agendarModal select,
        html.light-mode #editCitaOverlay input,
        html.light-mode #editCitaOverlay select {
            background: #f8fafc !important;
            border: 1px solid #cbd5e1 !important;
            color: #0f172a !important;
        }
        html.light-mode #agendarModal input:focus,
        html.light-mode #agendarModal select:focus,
        html.light-mode #editCitaOverlay input:focus,
        html.light-mode #editCitaOverlay select:focus {
            background: #ffffff !important;
            border-color: #64748b !important;
            box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.15) !important;
        }

        /* Placeholders (placeholder-white/20 de Tailwind) — visibles pero sin ruido. */
        html.light-mode #agendarModal input::placeholder,
        html.light-mode #editCitaOverlay input::placeholder,
        html.light-mode .placeholder-white\/20::placeholder {
            color: #94a3b8 !important;
            opacity: 1 !important;
        }

        /* Botones "X" de cerrar dentro de cada modal (bg-white/5 border-white/10) */
        html.light-mode #agendarModal button[onclick*="cerrarAgendar"],
        html.light-mode #editCitaOverlay button[onclick*="cerrarEditar"] {
            background: #f1f5f9 !important;
            border-color: #e2e8f0 !important;
        }
        html.light-mode #agendarModal button[onclick*="cerrarAgendar"] i,
        html.light-mode #editCitaOverlay button[onclick*="cerrarEditar"] i {
            color: #475569 !important;
        }

        /* Dropdown de sugerencias del buscador de clientes (#1c1c26 → rgb(28,28,38)) */
        html.light-mode #manualNameSugg,
        html.light-mode [style*="background:var(--elev-surface-2)"],
        html.light-mode [style*="background:var(--elev-surface-2)"],
        html.light-mode [style*="background:rgb(28, 28, 38)"] {
            background: #ffffff !important;
            border: 1px solid #e2e8f0 !important;
            box-shadow: 0 8px 32px rgba(15, 23, 42, 0.15) !important;
        }

        /* <option> con style inline background:#111 → rgb(17,17,17) */
        html.light-mode select option[style*="background:#111"],
        html.light-mode select option[style*="background: #111"],
        html.light-mode select option[style*="background:rgb(17, 17, 17)"],
        html.light-mode select option[style*="background:rgb(17,17,17)"] {
            background: #ffffff !important;
            color: #0f172a !important;
        }

        /* Botón principal "Guardar Cita Confirmada" — bg-brand-accent dorado.
           Refuerzo del texto para lectura. */
        html.light-mode #manualSaveBtn {
            color: #0f172a !important;
            font-weight: 800 !important;
        }

        /* ── (B) Vista SEMANA — bloque eliminado.
           Antes: attribute-selectors [style*="rgb(20, 20, 24)"] y variantes
           normalizadas que perseguían los cssText emitidos por renderWeekView.
           Ahora renderWeekView lee document.documentElement.classList y pinta
           con `pal.*`, así que este bloque es innecesario. Se mantienen abajo
           sólo los overrides que apuntan al HTML estático (modales, backdrops)
           y al select native option[style="..."] que también viene del markup. */

        /* Ambient blancos casi invisibles (0.02..0.06) — contenedores decorativos */
        html.light-mode [style*="rgba(255, 255, 255, 0.02)"],
        html.light-mode [style*="rgba(255, 255, 255, 0.04)"],
        html.light-mode [style*="rgba(255, 255, 255, 0.05)"] {
            background: #f8fafc !important;
        }

        /* Backdrops de otros overlays que no cubrí antes (calendario mini,
           notif toast) — mismo tratamiento. */
        html.light-mode [style*="background:rgba(0,0,0,0.7)"],
        html.light-mode [style*="background: rgba(0, 0, 0, 0.7)"] {
            background: rgba(15, 23, 42, 0.4) !important;
        }
        html.light-mode [style*="background:rgba(0,0,0,0.78)"],
        html.light-mode [style*="background:rgba(0,0,0,0.93)"] {
            background: rgba(15, 23, 42, 0.5) !important;
        }

        /* Bordes inline del modal edit sheet (border-top rgba blanca) */
        html.light-mode [style*="border-top:1px solid rgba(255,255,255,0.08)"],
        html.light-mode [style*="border-top: 1px solid rgba(255, 255, 255, 0.08)"] {
            border-top-color: #e2e8f0 !important;
        }

        /* ═══════════════════════════════════════════════════════════════════
           QUINTA PASADA — Mobile-First UX del barbero.
           Aplica en ambos modos (no está namespaced a light-mode).
           ═══════════════════════════════════════════════════════════════════ */

        /* (2) Header compacto en mobile — mueve los botones secundarios al
              kebab. Deja visibles solo notificaciones + WhatsApp + kebab. */
        @media (max-width: 639px) {
            header.sticky {
                padding-left: 1rem !important;
                padding-right: 0.75rem !important;
                padding-top: calc(env(safe-area-inset-top, 0px) + 0.85rem) !important;
                padding-bottom: 0.85rem !important;
            }
            #theme-toggle,
            #reloadBtn,
            #btnSignOut,
            #btnHome { display: none !important; }
            /* "EN VIVO" al lado del nombre en la misma línea */
            #barberLiveWrap {
                flex-direction: row !important;
                align-items: center !important;
                gap: 0.5rem !important;
                margin-top: 0 !important;
            }
            /* Header en UNA línea: burger · logo · nombre+EN VIVO. Antes iba en
               columna (logo arriba, nombre abajo). */
            #barberHeaderBlock { flex-direction: row; align-items: center; }
        }


        /* Panel dropdown del kebab con transición suave */
        /* El open/close del panel (bottom-sheet) lo maneja el transform inline
           + la clase .hidden estandar (display:none) — ver abrirKebabMenu() /
           closeKebabMenu(). Antes esto era un dropdown con fade+scale desde
           la esquina superior derecha y un `.hidden{display:block!important}`
           que lo mantenia en el layout pero invisible; con el panel ahora
           `position:fixed`, ese override dejaba el panel VISIBLE (achicado,
           semi-transparente) incluso "cerrado". Se retira entero. */

        /* (3) Estilos de citas — más padding + contraste refinado.
              padding-inline extra da respiración al bloque "Hora/Servicio". */
        .cita-card { padding: 1rem 1.1rem !important; }
        @media (min-width: 768px) {
            .cita-card { padding: 1.15rem 1.35rem !important; }
        }

        /* ── Tinte por estado: el color pinta la TARJETA, no solo el borde ──

           El 10, 04-09-2026 (Danilo): "el fondo oscuro molesta la visión de
           colores… con el modo claro se ve todo igual, no se diferencia de las
           que están pagadas y de las que está confirmada". Tenía razón dos
           veces: en oscuro solo Completada (14%) y Confirmada (12%) tenían
           tinte —apenas—, y en claro NINGUNA: todas caían al pastel azul de
           `html.light-mode .bg-[#1c1c24]` y el único distintivo era el borde
           izquierdo de 4px.

           El color sigue saliendo de las variables --st-* para respetar la
           paleta que el local eligió en Configuración → Colores de la agenda.

           Cancelada NO lleva tinte a propósito: su tarjeta va con
           `opacity-40 grayscale`, y el filtro convertiría cualquier tinte en
           gris de todos modos. Su identidad ES estar apagada — la única gris
           de la lista se reconoce sola.

           El :hover repite la regla un punto más profundo: estas reglas van
           DESPUÉS de `html.light-mode .hover:bg-[#22222c]:hover` (línea ~530)
           y a igual especificidad gana el orden — sin la variante :hover, el
           tinte se comería el feedback del cursor en escritorio. */

        /* Modo oscuro — tinte sobre el gris de la tarjeta. */
        html:not(.light-mode) .cita-card[data-estado="Completada"]  { background: color-mix(in srgb, var(--st-completada) 22%, #14151a) !important; }
        html:not(.light-mode) .cita-card[data-estado="Confirmada"]  { background: color-mix(in srgb, var(--st-confirmada) 18%, #14151a) !important; }
        html:not(.light-mode) .cita-card[data-estado="Pendiente"]   { background: color-mix(in srgb, var(--st-pendiente) 13%, #14151a) !important; }
        html:not(.light-mode) .cita-card[data-estado="NoAsistio"]   { background: color-mix(in srgb, var(--st-noasistio) 16%, #14151a) !important; }
        html:not(.light-mode) .cita-card[data-estado="Completada"]:hover  { background: color-mix(in srgb, var(--st-completada) 27%, #191a21) !important; }
        html:not(.light-mode) .cita-card[data-estado="Confirmada"]:hover  { background: color-mix(in srgb, var(--st-confirmada) 23%, #191a21) !important; }
        html:not(.light-mode) .cita-card[data-estado="Pendiente"]:hover   { background: color-mix(in srgb, var(--st-pendiente) 18%, #191a21) !important; }
        html:not(.light-mode) .cita-card[data-estado="NoAsistio"]:hover   { background: color-mix(in srgb, var(--st-noasistio) 21%, #191a21) !important; }

        /* LLEGÓ (checkedInAt): pisa el tinte de su estado — el dato "está en
           el local" vale más que "prometió venir". El atributo solo se emite
           en citas vivas (ni Completada ni Cancelada), así que no compite con
           el verde de éxito. Va DESPUÉS de las reglas por estado a la misma
           especificidad doble-atributo, y gana por orden. */
        html:not(.light-mode) .cita-card[data-llego="1"] { background: color-mix(in srgb, var(--st-llegada) 22%, #14151a) !important; border-left-color: var(--st-llegada) !important; }
        html:not(.light-mode) .cita-card[data-llego="1"]:hover { background: color-mix(in srgb, var(--st-llegada) 27%, #191a21) !important; }

        /* Modo claro — el mismo tinte, mezclado sobre blanco: pasteles que se
           distinguen entre sí de un vistazo. El texto sigue siendo el tinta
           #0f172a de html.light-mode .cita-card, legible sobre todos.

           INTENSIDAD (05-09-2026): subido de 14-18% a 26-32%, en la misma
           tanda que las clases .st-* del panel (index.css). Los dos paneles
           pintan el MISMO estado de la MISMA cita: si uno se intensifica y el
           otro no, el barbero y el dueño ven colores distintos del mismo
           dato. El texto de esta vista es tinta fija (#0f172a), así que subir
           el fondo solo mejora el contraste.

           INTENSIDAD (04-10-2026): 26-32% → 36-42%, a pedido de Ignacio ("más
           fuertes"), de nuevo junto con .st-* del panel. La tinta #0f172a
           queda sobre 10:1 en todos; los grises de adentro se oscurecen un
           paso (servicio y duración #334155) para no bajar de 4.5:1. */
        html.light-mode .cita-card .text-white\/55 { color: #334155 !important; }
        html.light-mode .cita-card .text-white\/30 { color: #334155 !important; }
        html.light-mode .cita-card[data-estado="Completada"]  { background: color-mix(in srgb, var(--st-completada) 40%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="Confirmada"]  { background: color-mix(in srgb, var(--st-confirmada) 40%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="Pendiente"]   { background: color-mix(in srgb, var(--st-pendiente) 42%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="NoAsistio"]   { background: color-mix(in srgb, var(--st-noasistio) 36%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="Completada"]:hover  { background: color-mix(in srgb, var(--st-completada) 48%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="Confirmada"]:hover  { background: color-mix(in srgb, var(--st-confirmada) 48%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="Pendiente"]:hover   { background: color-mix(in srgb, var(--st-pendiente) 50%, #ffffff) !important; }
        html.light-mode .cita-card[data-estado="NoAsistio"]:hover   { background: color-mix(in srgb, var(--st-noasistio) 44%, #ffffff) !important; }
        html.light-mode .cita-card[data-llego="1"] { background: color-mix(in srgb, var(--st-llegada) 42%, #ffffff) !important; border-left-color: var(--st-llegada) !important; }
        html.light-mode .cita-card[data-llego="1"]:hover { background: color-mix(in srgb, var(--st-llegada) 50%, #ffffff) !important; }

        /* La cita que importa ahora (ver _marcarCitaDestacada): un anillo y
           una etiqueta, sin tocar el tinte de su estado. */
        .cita-card[data-destacada] {
            box-shadow: 0 0 0 2px rgba(255,255,255,0.55), 0 10px 28px -10px rgba(0,0,0,0.6) !important;
            position: relative; z-index: 1;
        }
        html.light-mode .cita-card[data-destacada] {
            box-shadow: 0 0 0 2px rgba(15,23,42,0.55), 0 10px 24px -12px rgba(15,23,42,0.35) !important;
        }
        .cita-destacada-tag {
            flex-shrink: 0; padding: 2px 7px; border-radius: 9999px;
            font-size: 9.5px; font-weight: 900; letter-spacing: 0.08em; text-transform: uppercase;
            background: rgba(255,255,255,0.14); color: #fff;
        }
        .cita-card[data-destacada="ahora"] .cita-destacada-tag { background: var(--st-completada); color: #fff; }
        html.light-mode .cita-destacada-tag { background: #0f172a; color: #fff; }
        html.light-mode .cita-card[data-destacada="ahora"] .cita-destacada-tag { background: var(--st-completada); }
        /* Día que ya pasó: un punto más apagado. Las canceladas y no-show ya
           traen su propia opacidad: no se les suma. */
        #dayViewGrid.dia-pasado .cita-card:not(.opacity-40):not(.opacity-60) { opacity: 0.84; }

        /* (4) FAB — botón flotante para agregar cita rápida. Solo visible
              cuando #mainApp está montado. Safe-area para iPhone home indicator. */
        /* Slot libre en la grilla semanal (móvil-first).
           - min-height 44px = touch target de Apple (evita "casi no responde").
           - :active da feedback ANTES de que abra el modal (tap satisfactorio).
           - :hover solo aplica en dispositivos con puntero real (tablet+mouse).
           - user-select:none evita que un tap largo seleccione el "+" y bloquee
             el gesto de scroll o el segundo tap.
           Cuando el interval es 15min y hOf(interval) queda debajo de 44px, el
           min-height lo estira; los slots vecinos se solapan un poco pero el
           tap sigue siendo utilizable. Para 30/60min, el slot ya calza natural. */
        .week-empty-slot {
            min-height: 44px;
            user-select: none;
            -webkit-user-select: none;
            -webkit-tap-highlight-color: transparent;
            transition: background-color 75ms ease-out;
        }
        .week-empty-slot:active {
            background-color: rgba(38, 38, 38, 0.80) !important;
        }
        @media (hover: hover) and (pointer: fine) {
            .week-empty-slot:hover {
                background-color: rgba(38, 38, 38, 0.50) !important;
            }
        }
        /* ── Vista LISTA de la semana (agenda de papel) ───────────────── */
        .week-modo { display: inline-flex; padding: 3px; border-radius: 11px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08); }
        .week-modo button { display: inline-flex; align-items: center; gap: 5px; padding: 6px 11px; border-radius: 8px;
            font-size: 11px; font-weight: 800; color: rgba(255,255,255,.55); }
        .week-modo button.activo { background: rgba(255,255,255,.12); color: #fff; }
        .week-lista { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
        .week-lista__col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
        .week-lista__dia { flex: 1 0 auto; min-height: 132px; border-radius: 14px; overflow: hidden;
            background: #121215; border: 1px solid rgba(255,255,255,.08); display: flex; flex-direction: column; }
        .week-lista__dia.es-hoy { border-color: var(--accent, #c9a84c); box-shadow: 0 0 0 1px var(--accent, #c9a84c) inset; }
        .week-lista__cab { display: flex; align-items: baseline; gap: 6px; width: 100%; padding: 9px 11px 7px;
            border-bottom: 1px solid rgba(255,255,255,.07); text-align: left; }
        .week-lista__dow { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: rgba(255,255,255,.45); }
        .week-lista__num { font-size: 18px; font-weight: 900; color: #fff; line-height: 1; }
        .week-lista__cab .hoy { margin-left: auto; font-size: 9px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase;
            color: #0a0a0a; background: var(--accent, #c9a84c); padding: 2px 6px; border-radius: 6px; }
        .week-lista__cab .abrir { margin-left: auto; color: rgba(255,255,255,.3); font-size: 13px; }
        .week-lista__cab .hoy + .abrir { margin-left: 6px; }
        /* Cada cita en su renglón; el espacio libre de la hoja, rayado como
           cuaderno (así la hoja se lee aunque esté vacía). */
        .week-lista__hoja { flex: 1; display: flex; flex-direction: column; padding: 0 11px 8px; }
        .week-lista__relleno { flex: 1; min-height: 52px;
            background-image: repeating-linear-gradient(to bottom, transparent 0 25px, rgba(255,255,255,.07) 25px 26px); }
        .week-lista__cita { display: block; width: 100%; text-align: left; padding: 6px 0 5px;
            border-bottom: 1px solid rgba(255,255,255,.07);
            font-size: 13px; line-height: 1.25; color: rgba(255,255,255,.92); }
        .week-lista__cita .h { font-weight: 800; margin-right: 5px; color: var(--accent, #c9a84c);
            text-decoration: underline; text-decoration-color: rgba(255,255,255,.18); text-underline-offset: 3px; }
        .week-lista__cita .n { font-weight: 700; }
        .week-lista__cita .sv { display: block; font-size: 10.5px; color: rgba(255,255,255,.45); margin-top: 1px;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .week-lista__cita .st { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 5px; vertical-align: 2px; }
        .week-lista__vacio { font-size: 11px; color: rgba(255,255,255,.3); padding-top: 6px; }
        html.light-mode .week-modo { background: #f1f5f9; border-color: #e2e8f0; }
        html.light-mode .week-modo button { color: #64748b; }
        html.light-mode .week-modo button.activo { background: #fff; color: #0f172a; box-shadow: 0 1px 2px rgba(15,23,42,.1); }
        html.light-mode .week-lista__dia { background: #fff; border-color: #e2e8f0; }
        html.light-mode .week-lista__cab { border-color: #eef2f6; }
        html.light-mode .week-lista__dow { color: #64748b; }
        html.light-mode .week-lista__num { color: #0f172a; }
        html.light-mode .week-lista__cab .abrir { color: #94a3b8; }
        html.light-mode .week-lista__relleno { background-image: repeating-linear-gradient(to bottom, transparent 0 25px, #e8edf3 25px 26px); }
        html.light-mode .week-lista__cita { border-color: #e8edf3; }
        html.light-mode .week-lista__cita { color: #0f172a; }
        html.light-mode .week-lista__cita .sv { color: #64748b; }
        html.light-mode .week-lista__vacio { color: #94a3b8; }

        /* ── Calendario de la vista semana ─────────────────────────────── */
        .week-cal {
            position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%);
            z-index: 60; width: min(340px, calc(100vw - 32px));
            padding: 14px 14px 12px; border-radius: 18px;
            background: #111114; border: 1px solid rgba(255,255,255,.10);
            box-shadow: 0 24px 60px -12px rgba(0,0,0,.7);
        }
        .week-cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
        .week-cal__mes { font-size: 14px; font-weight: 800; color: #fff; text-transform: capitalize; }
        .week-cal__nav { width: 36px; height: 36px; display: grid; place-items: center; border-radius: 10px;
            color: rgba(255,255,255,.7); background: rgba(255,255,255,.05); }
        .week-cal__nav:active { transform: scale(.95); }
        .week-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
        .week-cal__dow { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-align: center;
            color: rgba(255,255,255,.35); padding: 4px 0 6px; }
        .week-cal__dia { position: relative; height: 40px; border-radius: 10px; font-size: 13px; font-weight: 600;
            color: rgba(255,255,255,.85); display: grid; place-items: center; }
        .week-cal__dia:hover { background: rgba(255,255,255,.07); }
        .week-cal__dia.es-semana { background: rgba(var(--accent-r,201),var(--accent-g,168),var(--accent-b,76),.14); border-radius: 0; }
        .week-cal__dia.es-semana.ini { border-radius: 10px 0 0 10px; }
        .week-cal__dia.es-semana.fin { border-radius: 0 10px 10px 0; }
        .week-cal__dia.es-hoy { color: #0a0a0a; }
        .week-cal__dia.es-hoy::before { content: ''; position: absolute; inset: 5px 6px; border-radius: 9px;
            background: var(--accent, #c9a84c); z-index: -1; }
        .week-cal__dia { isolation: isolate; }
        .week-cal__dia .punto { position: absolute; bottom: 5px; left: 50%; width: 4px; height: 4px; margin-left: -2px;
            border-radius: 50%; background: var(--accent, #c9a84c); }
        .week-cal__dia.es-hoy .punto { background: #0a0a0a; }
        .week-cal__pie { display: flex; justify-content: space-between; align-items: center; margin-top: 10px;
            padding-top: 10px; border-top: 1px solid rgba(255,255,255,.07); }
        .week-cal__hoy { font-size: 12px; font-weight: 800; color: var(--accent, #c9a84c); padding: 6px 10px; border-radius: 9px; }
        .week-cal__nota { font-size: 11px; color: rgba(255,255,255,.4); }
        html.light-mode .week-cal { background: #fff; border-color: #e2e8f0; box-shadow: 0 24px 60px -18px rgba(15,23,42,.35); }
        html.light-mode .week-cal__mes { color: #0f172a; }
        html.light-mode .week-cal__nav { color: #334155; background: #f1f5f9; }
        html.light-mode .week-cal__dow { color: #94a3b8; }
        html.light-mode .week-cal__dia { color: #1e293b; }
        html.light-mode .week-cal__dia:hover { background: #f1f5f9; }
        html.light-mode .week-cal__nota { color: #94a3b8; }
        html.light-mode .week-cal__pie { border-color: #eef2f6; }
        html.light-mode .week-cal-btn:hover { background: #f1f5f9; }
        html.light-mode .week-empty-slot:active {
            background-color: rgba(15, 23, 42, 0.10) !important;
        }
        html.light-mode .week-empty-slot .week-empty-slot__plus {
            color: rgba(15, 23, 42, 0.66) !important;   /* 0.58 quedaba en 4.3:1 (auditoría 04-10) */
        }
        .week-empty-slot__plus {
            font-size: 1.25rem;      /* text-xl */
            font-weight: 300;        /* font-light */
            color: #404040;          /* neutral-700 */
            line-height: 1;
            pointer-events: none;
        }

        /* Pestaña activa de la barra inferior: mismo criterio on/off que
           _pillPalette() (blanco=activo, medio-transparente=inactivo), pero
           acá el fondo lo da #navPill (que se desliza), no el botón mismo. */
        .nav-tab,
        .nav-action { color: rgba(255,255,255,0.5); transition: color .2s ease; }
        .nav-tab.nav-tab-active { color: #ffffff; }
        #bottomNav #navPill { transition: transform .38s cubic-bezier(0.16,1,0.3,1), opacity .2s ease; }
        #bottomNav.menu-open #navPill { opacity: 0; }
        .nav-action.nav-menu-active { color: #ffffff; }
        html.light-mode #bottomNav > div { background: rgba(255,255,255,0.92) !important; border-top-color: #e2e8f0 !important; }
        html.light-mode #navPill { background: rgba(15,23,42,0.08) !important; }
        html.light-mode .nav-tab,
        html.light-mode .nav-action { color: #64748b; }
        html.light-mode .nav-tab.nav-tab-active { color: #0f172a; }
        html.light-mode .nav-action.nav-menu-active { color: #0f172a; }

        /* Proyección deja de ser un modal flotante en móvil y pasa a ocupar el
           mismo nivel de contenido que Hoy/Semana. En escritorio conserva el
           modal original, que sigue siendo apropiado junto al panel lateral. */
        @media (max-width: 639.98px) {
            #proyeccionModal.mobile-projection-view {
                position: relative !important;
                inset: auto !important;
                z-index: auto !important;
                display: block !important;
                width: 100% !important;
                padding: 0 !important;
                margin: 0 0 2rem !important;
                scroll-margin-top: calc(env(safe-area-inset-top, 0px) + 76px);
                background: transparent !important;
                backdrop-filter: none !important;
                -webkit-backdrop-filter: none !important;
            }
            #proyeccionModal.mobile-projection-view > div {
                width: 100% !important;
                max-width: none !important;
                padding: 1rem !important;
                margin-top: 0.75rem !important;
                border-radius: 1.25rem !important;
                box-shadow: none !important;
                animation: viewIn .18s ease;
            }
            #proyeccionModal.mobile-projection-view .projection-close-btn {
                display: none !important;
            }
            #errBanner {
                /* Android no siempre informa safe-area con navegación de tres
                   botones. Reservamos un mínimo físico además de la barra app. */
                bottom: calc(max(env(safe-area-inset-bottom, 0px), 24px) + 12px + var(--bottom-nav-h)) !important;
                width: calc(100vw - 24px);
                max-width: 420px !important;
                padding: 9px 9px 9px 12px !important;
                gap: 8px !important;
                border-radius: 16px !important;
            }
            #errBanner .err-banner-message {
                flex: 1;
                min-width: 0;
                white-space: normal !important;
                line-height: 1.2;
            }
        }

        /* El título de fecha entra con la misma dirección que la agenda, pero
           con un recorrido corto para que el texto nunca choque con los
           controles laterales durante el cambio de día. */
        @keyframes dateTitleInNext {
            from { opacity: 0; transform: translateX(8px); }
            to   { opacity: 1; transform: translateX(0); }
        }
        @keyframes dateTitleInPrev {
            from { opacity: 0; transform: translateX(-8px); }
            to   { opacity: 1; transform: translateX(0); }
        }
        .date-title-in-next { animation: dateTitleInNext .22s cubic-bezier(0.22,1,0.36,1); }
        .date-title-in-prev { animation: dateTitleInPrev .22s cubic-bezier(0.22,1,0.36,1); }
        @keyframes dayStripInNext {
            from { opacity: .72; transform: translateX(18px); }
            to   { opacity: 1; transform: translateX(0); }
        }
        @keyframes dayStripInPrev {
            from { opacity: .72; transform: translateX(-18px); }
            to   { opacity: 1; transform: translateX(0); }
        }
        @keyframes dayChipSelectedIn {
            0%   { opacity: .72; transform: scale(.94) translateY(2px); }
            62%  { opacity: 1; transform: scale(1.075) translateY(-1px); }
            100% { opacity: 1; transform: scale(1.05) translateY(0); }
        }
        @keyframes dayChipReleased {
            0%   { opacity: .82; transform: scale(1.045); }
            100% { opacity: 1; transform: scale(1); }
        }
        .day-strip-in-next { animation: dayStripInNext .28s cubic-bezier(0.22,1,0.36,1) both; }
        .day-strip-in-prev { animation: dayStripInPrev .28s cubic-bezier(0.22,1,0.36,1) both; }
        .day-chip-selected-in { animation: dayChipSelectedIn .32s cubic-bezier(0.22,1,0.36,1) both; }
        .day-chip-released { animation: dayChipReleased .24s ease-out both; }
        .date-month-mobile { color: rgba(255,255,255,0.48); }
        html.light-mode .date-month-mobile { color: #64748b; }
        @media (prefers-reduced-motion: reduce) {
            .date-title-in-next,
            .date-title-in-prev,
            .day-strip-in-next,
            .day-strip-in-prev,
            .day-chip-selected-in,
            .day-chip-released { animation: none; }
        }
        #fabNuevaCita {
            position: fixed;
            right: 1.5rem;
            bottom: calc(max(1.5rem, calc(env(safe-area-inset-bottom, 0px) + 1rem)) + var(--bottom-nav-h));
            width: auto;
            min-width: 3.5rem;
            height: 3.5rem;
            padding: 0 1.15rem;
            gap: 0.55rem;
            border-radius: 9999px;
            display: none;              /* JS lo muestra al cargar mainApp */
            align-items: center;
            justify-content: center;
            background: #10b981;
            color: #ffffff;
            box-shadow: 0 10px 24px -6px rgba(16, 185, 129, 0.45),
                        0 4px 10px rgba(0, 0, 0, 0.25);
            z-index: 45;
            transition: transform 0.15s ease, box-shadow 0.2s ease, width 0.2s ease, padding 0.2s ease;
            border: none;
            cursor: pointer;
            overflow: hidden;
        }
        /* Agenda de solo lectura: ver _activarSoloLectura(). */
        html.agenda-solo-lectura #fabNuevaCita,
        html.agenda-solo-lectura #fabNuevaCita.visible,
        html.agenda-solo-lectura #porCerrarBanner,
        html.agenda-solo-lectura .cd-nota-btn,
        html.agenda-solo-lectura [onclick*="abrirCobroRapido"],
        html.agenda-solo-lectura [onclick*="marcarLlegadaCita"],
        html.agenda-solo-lectura [onclick*="abrirEditarCita"],
        html.agenda-solo-lectura [onclick*="cambiarEstadoDesdeDetalle"],
        html.agenda-solo-lectura [onclick*="cambiarEstadoCita"],
        html.agenda-solo-lectura [onclick*="removerBloqueoRapido"],
        html.agenda-solo-lectura [onclick*="_agendaCanjearPack"],
        html.agenda-solo-lectura [onclick*="abrirVenderProducto"] { display: none !important; }
        /* La hora libre y el "llegó a las 10:05" se siguen VIENDO; solo dejan de responder al toque. */
        html.agenda-solo-lectura .agenda-free-slot,
        html.agenda-solo-lectura [onclick*="deshacerLlegadaCita"] { pointer-events: none; cursor: default; }
        #fabNuevaCita:hover  { transform: translateY(-1px); }
        #fabNuevaCita:active { transform: scale(0.94); }
        #fabNuevaCita.visible { display: flex; }
        #fabNuevaCita .fab-label {
            max-width: 8rem;
            opacity: 1;
            overflow: hidden;
            white-space: nowrap;
            font-size: 0.82rem;
            font-weight: 800;
            transition: max-width 0.2s ease, opacity 0.15s ease;
        }
        #fabNuevaCita.fab-compact {
            width: 3.5rem;
            padding-left: 0;
            padding-right: 0;
            gap: 0;
        }
        #fabNuevaCita.fab-compact .fab-label {
            max-width: 0;
            opacity: 0;
            display: none;
        }
        #fabNuevaCita.projection-fab {
            width: 3.25rem !important;
            min-width: 3.25rem !important;
            max-width: 3.25rem !important;
            padding-left: 0 !important;
            padding-right: 0 !important;
            gap: 0 !important;
        }
        #fabNuevaCita.projection-fab .fab-label { display: none !important; }
        @media (max-width: 1023px) {
            #fabNuevaCita.fab-compact { width: 3.25rem; }
            body:not(.fab-is-compact) .agenda-free-slot { padding-right: 10rem !important; }
        }

        /* ── Una sola vista a la vez (celular) — 04-10 ─────────────────────
           Revisión de la agenda de Stiven Barber en un iPhone:
           - "Instalar la app" y "N citas por cerrar" se repetían arriba de
             Hoy, Semana y Ganancias (~¼ de pantalla antes de la fecha). Ahora
             solo en Hoy, y "por cerrar" es un chip del resumen: la franja con
             la lista aparece solo al abrirlo.
           - El FAB con texto ("Nueva cita") tapaba el precio de la primera
             cita y en Ganancias tapaba "Mis propinas". En el celular va
             siempre como "+", y solo en Hoy y Semana. */
        @media (max-width: 639.98px) {
            html[data-vista-movil]:not([data-vista-movil="dia"]) #pwaBigInstallCard,
            html[data-vista-movil]:not([data-vista-movil="dia"]) #porCerrarBanner,
            #porCerrarBanner:not(.pc-abierto) { display: none !important; }

            html[data-vista-movil="proyeccion"] #fabNuevaCita,
            html[data-vista-movil="novedades"] #fabNuevaCita { display: none !important; }
            #fabNuevaCita {
                width: 3.25rem; padding-left: 0; padding-right: 0; gap: 0;
            }
            #fabNuevaCita .fab-label { display: none !important; }
            /* Sin el FAB ancho, el carril de 10rem que se le reservaba sobra. */
            body:not(.fab-is-compact) .agenda-free-slot { padding-right: 5rem !important; }
        }
        @media (min-width: 640px) {
            #chipPorCerrar { display: none !important; }
        }
        html.agenda-solo-lectura #chipPorCerrar { display: none !important; }

        /* Contador de citas junto a "Por la mañana / Por la tarde": en modo
           claro era texto blanco sobre fondo blanco y no se veía. */
        .tramo-count {
            margin-left: auto; padding: 2px 8px; border-radius: 9999px;
            font-size: 10px; font-weight: 700;
            background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.5);
        }
        html.light-mode .tramo-count { background: rgba(15,23,42,0.06); color: #475569; }

        /* ══ AUDITORÍA DEL MODO CLARO (04-10-2026) ═══════════════════════════
           Recorrido ventana por ventana con la cuenta de un barbero de Stiven
           Barber, midiendo el contraste de cada texto contra su fondo real.
           Lo que se arregla acá, por causa:

           1) VENTANAS ARMADAS PARA OSCURO. Cobro rápido, SII, comisiones,
              propinas, pack del día y vender usan estilos EN LÍNEA de oscuro
              (blanco y blancos translúcidos fijos). En claro quedaban hojas
              negras o, peor, textos que el claro sí oscurecía sobre un fondo
              que seguía negro (comisiones: el título y los montos a 1.1:1).
              Una sola clase, .claro-invertible, les da vuelta los valores en
              línea típicos. Los botones con fondo sólido (`background:#…`)
              conservan su texto. */
        html.light-mode .claro-invertible {
            background: #ffffff !important;
            border-color: #e2e8f0 !important;
            box-shadow: 0 -8px 40px rgba(15,23,42,0.18) !important;
            color-scheme: light;
        }
        html.light-mode #comisionesModal.claro-invertible,
        html.light-mode #propinasModal.claro-invertible { background: #f8fafc !important; box-shadow: none !important; }
        html.light-mode .claro-invertible [style*="color:#fff"]:not([style*="background:#"]),
        html.light-mode .claro-invertible [style*="color: #fff"]:not([style*="background:#"]),
        html.light-mode .claro-invertible [style*="color:white"]:not([style*="background:#"]) { color: #0f172a !important; }
        html.light-mode .claro-invertible [style*="color:rgba(255,255,255"],
        html.light-mode .claro-invertible [style*="color: rgba(255,255,255"] { color: #475569 !important; }
        html.light-mode .claro-invertible [style*="background:rgba(255,255,255"],
        html.light-mode .claro-invertible [style*="background: rgba(255,255,255"] { background: #f1f5f9 !important; }
        html.light-mode .claro-invertible [style*="solid rgba(255,255,255"],
        html.light-mode .claro-invertible [style*="solid rgba(30,41,59"] { border-color: #e2e8f0 !important; }
        html.light-mode .claro-invertible [style*="color-scheme:dark"] { color-scheme: light !important; }
        html.light-mode .claro-invertible input,
        html.light-mode .claro-invertible textarea,
        html.light-mode .claro-invertible select { background: #f8fafc !important; color: #0f172a !important; border-color: #cbd5e1 !important; }
        html.light-mode .claro-invertible [style*="color:#6ee7b7"],
        html.light-mode .claro-invertible [style*="color:#a7f3d0"] { color: #047857 !important; }
        html.light-mode .claro-invertible [style*="color:rgba(96,165,250"],
        html.light-mode .claro-invertible [style*="color:#93c5fd"],
        html.light-mode .claro-invertible [style*="color:#60a5fa"] { color: #1d4ed8 !important; }
        html.light-mode .claro-invertible [style*="color:#fecaca"],
        html.light-mode .claro-invertible [style*="color:#fca5a5"],
        html.light-mode .claro-invertible [style*="color:#fda4af"] { color: #b91c1c !important; }
        /* Grises slate fijos, pensados como "texto claro sobre navy" (SII). */
        html.light-mode .claro-invertible [style*="color:#e2e8f0"] { color: #1e293b !important; }
        html.light-mode .claro-invertible [style*="color:#cbd5e1"] { color: #334155 !important; }
        html.light-mode .claro-invertible [style*="color:#94a3b8"],
        html.light-mode .claro-invertible [style*="color:rgba(148,163,184"] { color: #475569 !important; }
        html.light-mode .claro-invertible [style*="background:rgba(2,6,23"],
        html.light-mode .claro-invertible [style*="background:rgba(15,23,42"] { background: #f1f5f9 !important; }
        /* Los grises por clase (/30-/50) caen sobre el #f1f5f9 de las filas:
           ahí #64748b queda en 4.3:1, un paso más oscuro. */
        html.light-mode .claro-invertible .text-white\/50,
        html.light-mode .claro-invertible .text-white\/45,
        html.light-mode .claro-invertible .text-white\/40,
        html.light-mode .claro-invertible .text-white\/35,
        html.light-mode .claro-invertible .text-white\/30 { color: #475569 !important; }
        /* Botones verdes con texto blanco: en claro el #10b981 / #059669 deja
           el blanco a 2.5-3.8:1. Se usa el verde de texto (#047857, 5.5:1). */
        html.light-mode #notifPermPrimary,
        html.light-mode .claro-invertible [style*="background:#059669"] { background: #047857 !important; }

        /* 2) ACENTOS PENSADOS PARA FONDO NEGRO. Dorado #c9a84c / #e8c96b,
              verde #34d399, ámbar #fcd34d / #fbbf24 en línea: sobre blanco o
              crema quedaban entre 1.4:1 y 2.3:1 ("Ofrecer esta hora", "Abrir"
              y "Guardar QR" del perfil, el aviso de bloquear el mes). Se
              oscurecen un paso: dorado #7c5e1a (6:1), verde #047857 (5.5:1),
              ámbar #92400e (7:1). El saludo de llegada es una pastilla oscura
              también en claro: se excluye. */
        html.light-mode [style*="color:#c9a84c"],
        html.light-mode [style*="color: #c9a84c"],
        html.light-mode [style*="color:#e8c96b"],
        html.light-mode [style*="color: #e8c96b"] { color: #7c5e1a !important; }
        html.light-mode [style*="color:#34d399"]:not(#welcomeToast *),
        html.light-mode [style*="color: #34d399"]:not(#welcomeToast *) { color: #047857 !important; }
        html.light-mode [style*="color:#fcd34d"]:not(#loginOverlay *),
        html.light-mode [style*="color:#fbbf24"]:not(#loginOverlay *) { color: #92400e !important; }
        html.light-mode .text-brand-accent,
        html.light-mode .text-brand-accent\/80,
        html.light-mode .text-brand-accent\/60,
        html.light-mode .text-brand-accent\/50 { color: #7c5e1a !important; }
        html.light-mode .text-amber-400,
        html.light-mode .text-amber-300 { color: #92400e !important; }
        html.light-mode .text-sky-400 { color: #0369a1 !important; }

        /* 3) GRISES DEMASIADO CLAROS. /30 y /35 iban a #94a3b8 (2.6:1 sobre
              blanco): etiquetas como "Estado", los días del mini calendario,
              ayudas. Pasan a #64748b (4.8:1). /20 sigue clarito: es decorado. */
        html.light-mode .text-white\/35,
        html.light-mode .text-white\/30 { color: #64748b !important; }
        /* Sobre el ámbar de "por cerrar" el #64748b no alcanza: un paso más. */
        html.light-mode #porCerrarBanner .text-white\/45,
        html.light-mode #porCerrarBanner .text-white\/50 { color: #475569 !important; }

        /* 4) DENTRO DE LAS TARJETAS DE CITA el tinte es más fuerte: los
              chips verdes ("Confirmada", "Producto", "Primera visita") van a
              #064e3b y "Sobrecupo" a #451a03: siguen sobre 4.5:1 también en días
              pasados, donde la tarjeta va a 0.84 de opacidad. */
        html.light-mode .cita-card .text-emerald-400,
        html.light-mode .cita-card .text-emerald-300 { color: #064e3b !important; }
        html.light-mode .cita-card .text-amber-400,
        html.light-mode .cita-card .text-amber-300 { color: #451a03 !important; }

        /* Light mode: FAB con emerald más profundo para no quemar el ojo */
        html.light-mode #fabNuevaCita {
            background: #059669;
            box-shadow: 0 10px 24px -6px rgba(5, 150, 105, 0.45),
                        0 4px 10px rgba(15, 23, 42, 0.15);
        }

        /* El permiso es una interrupción modal real: debe cubrir navegación y
           FAB, y la acción afirmativa conserva la jerarquía en ambos temas. */
        #notifPermModal { isolation: isolate; }
        #notifPermPrimary {
            background: #10b981 !important;
            color: #ffffff !important;
            border: 1px solid #34d399 !important;
            box-shadow: 0 8px 20px rgba(16,185,129,0.28);
        }
        #notifPermSecondary {
            background: transparent !important;
            color: rgba(255,255,255,0.52) !important;
            border: 0 !important;
            box-shadow: none !important;
        }
        html.light-mode #notifPermSecondary { color: #64748b !important; }

        @media (max-width: 639.98px) {
            #loginOverlay {
                justify-content: flex-start !important;
                overflow-y: auto;
                padding-top: max(24px, calc(env(safe-area-inset-top, 0px) + 16px));
                padding-bottom: max(40px, calc(env(safe-area-inset-bottom, 0px) + 28px));
            }
            #loginOverlay > .login-shell { margin-top: auto; margin-bottom: auto; }
        }

        /* Resumen operativo: la proxima cita debe leerse como una tarjeta y
           no como otro filtro gris dentro de la cabecera. */
        #nextCitaChip {
            min-height: 64px;
            padding: 0.75rem 0.9rem !important;
            border-color: rgba(52, 211, 153, 0.24) !important;
            background: linear-gradient(135deg, rgba(16,185,129,0.11), rgba(255,255,255,0.035)) !important;
        }
        #nextCitaChip.is-empty {
            min-height: 44px;
            background: rgba(255,255,255,0.035) !important;
            border-color: var(--elev-border) !important;
        }
        #nextCitaEyebrow { color: rgba(52,211,153,0.82); }
        #nextCitaChip.is-empty #nextCitaEyebrow { color: rgba(255,255,255,0.42); }
        html.light-mode #nextCitaChip {
            background: linear-gradient(135deg, #ecfdf5, #ffffff) !important;
            border-color: #a7f3d0 !important;
            box-shadow: 0 1px 3px rgba(15,23,42,0.06);
        }
        html.light-mode #nextCitaChip.is-empty {
            background: #ffffff !important;
            border-color: #e2e8f0 !important;
        }
        html.light-mode #nextCitaEyebrow { color: #047857 !important; }
        html.light-mode #nextCitaChip.is-empty #nextCitaEyebrow { color: #64748b !important; }
        html.light-mode #nextCitaMeta { color: #64748b !important; }

        .agenda-free-action-label {
            color: rgba(255,255,255,0.58);
            font-size: 11px;
            font-weight: 800;
        }
        .agenda-free-slot:hover .agenda-free-action-label { color: rgba(255,255,255,0.92); }
        html.light-mode .agenda-free-action-label { color: #475569 !important; }
        html.light-mode .agenda-free-slot:hover .agenda-free-action-label { color: #0f172a !important; }

        #desktopEmptyState .desktop-overview-card {
            background: rgba(255,255,255,0.035);
            border: 1px solid rgba(255,255,255,0.08);
        }
        html.light-mode #desktopEmptyState .desktop-overview-card {
            background: #f8fafc !important;
            border-color: #e2e8f0 !important;
        }
        html.light-mode #desktopEmptyState .desktop-overview-value { color: #0f172a !important; }
        html.light-mode #desktopEmptyState .desktop-overview-label { color: #64748b !important; }

        .latest-reservation-contact-hint {
            color: rgba(255,255,255,0.42);
            font-size: 10px;
        }
        html.light-mode .latest-reservation-contact-hint { color: #64748b !important; }

        /* Filtros compactos del historial de actividad. El feed abre en Hoy
           para que las novedades operativas no se pierdan entre semanas de
           eventos, y el usuario expande el rango solo cuando lo necesita. */
        #actividadFiltros {
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            background: rgba(255,255,255,0.045);
            border: 1px solid rgba(255,255,255,0.08);
        }
        #actividadFiltros button {
            color: rgba(255,255,255,0.52);
        }
        #actividadFiltros button[aria-pressed="true"] {
            background: #ffffff;
            color: #0a0a0a;
            box-shadow: 0 2px 8px rgba(0,0,0,0.22);
        }
        html.light-mode #actividadFiltros {
            background: #f1f5f9 !important;
            border-color: #cbd5e1 !important;
        }
        html.light-mode #actividadFiltros button { color: #475569 !important; }
        html.light-mode #actividadFiltros button[aria-pressed="true"] {
            background: #0f172a !important;
            color: #ffffff !important;
            box-shadow: 0 2px 6px rgba(15,23,42,0.18);
        }
        html.light-mode #actividadResumen { color: #64748b !important; }

        /* (5) Botón flotante "🎯 Ahora" — pill compacta encima del FAB.
              Scrollea al #nowIndicator que renderSlots inserta cuando el
              día visible es hoy. Solo visible cuando hay algo a lo que ir. */
        #btnScrollAhora {
            position: fixed;
            right: 1.5rem;
            /* FAB (56px) + gap 12px por encima del FAB, + la barra inferior */
            bottom: calc(max(1.5rem, env(safe-area-inset-bottom, 0px) + 1rem) + 3.5rem + 0.75rem + var(--bottom-nav-h));
            display: none;
            align-items: center;
            gap: 0.4rem;
            padding: 0.5rem 0.9rem;
            border-radius: 9999px;
            background: rgba(15, 23, 42, 0.9);
            color: #ffffff;
            font-size: 0.8rem;
            font-weight: 700;
            border: 1px solid rgba(255, 255, 255, 0.12);
            box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
            z-index: 44;
            cursor: pointer;
            transition: transform 0.15s ease, background 0.15s ease;
            backdrop-filter: blur(6px);
            -webkit-backdrop-filter: blur(6px);
        }
        #btnScrollAhora:hover  { transform: translateY(-1px); }
        #btnScrollAhora:active { transform: scale(0.95); }
        #btnScrollAhora.visible { display: inline-flex; }
        html.light-mode #btnScrollAhora {
            background: #ffffff;
            color: #0f172a;
            border-color: #e2e8f0;
            box-shadow: 0 6px 16px rgba(15, 23, 42, 0.15);
        }

        /* Kebab dropdown items — hover + safe-area */
        #kebabMenuPanel [data-menu-item] {
            display: flex;
            align-items: center;
            gap: 0.65rem;
            padding: 0.7rem 0.85rem;
            border-radius: 0.65rem;
            font-size: 0.85rem;
            font-weight: 600;
            width: 100%;
            text-align: left;
            transition: background-color 0.12s ease;
            color: #ffffff;
        }
        #kebabMenuPanel [data-menu-item]:hover {
            background: rgba(255, 255, 255, 0.06);
        }
        html.light-mode #kebabMenuPanel [data-menu-item] { color: #0f172a; }
        html.light-mode #kebabMenuPanel [data-menu-item]:hover {
            background: #f1f5f9;
        }
        /* Override del fondo #0f0f12 inline del panel en modo claro */
        html.light-mode #kebabMenuPanel {
            background: #ffffff !important;
            border-color: #e2e8f0 !important;
            box-shadow: 0 10px 30px rgba(15, 23, 42, 0.15) !important;
        }
        html.light-mode #kebabMenuPanel [style*="rgba(255,255,255,0.06)"] {
            background: #e2e8f0 !important; /* divisor entre items */
        }
        /* Login: grupo de campos inset estilo iOS. El foco lo maneja el
           contenedor (:focus-within), no cada input. El login siempre es
           oscuro, por eso los colores van fijos (no vars de tema). */
        #loginFields:focus-within {
            border-color: rgba(255,255,255,0.3);
            box-shadow: 0 0 0 4px rgba(255,255,255,0.05);
        }
        #loginFields input::placeholder { color: rgba(255,255,255,0.42); }
        /* Evita el fondo azul/blanco del autofill del navegador sobre el
           input transparente oscuro y mantiene el texto legible. */
        #loginFields input:-webkit-autofill,
        #loginFields input:-webkit-autofill:hover,
        #loginFields input:-webkit-autofill:focus {
            -webkit-text-fill-color: #fff;
            caret-color: #fff;
            -webkit-box-shadow: 0 0 0 1000px rgba(30,30,36,0.9) inset;
            transition: background-color 9999s ease-in-out 0s;
        }

        /* El SII ya no se anuncia arriba de la agenda: su puerta es el Menú
           (_syncMenuSii). Se ocultan acá y no en el JS que los pinta para no
           pelear con ese código. */
        #siiBanner, #mandatoBanner { display: none !important; }
        html.light-mode #ecFechaAviso.text-amber-300 { color:#b45309; }

        /* ── Login: marca, tarjeta, botones y pie ─────────────────────────
           Siempre oscuro (colores fijos, no vars de tema). Las medidas están
           pensadas para que TODO —incluido el pie— entre en un iPhone SE
           (375×667) sin scroll: antes medía 731 px y "¿Olvidaste tu
           contraseña?" quedaba en el borde. El hover vive acá y no en
           onmouseover inline. */
        .login-marca { display:flex; flex-direction:column; align-items:center; text-align:center; margin-bottom:1.4rem; }
        .login-logo { position:relative; margin-bottom:0.9rem; display:flex; align-items:center; justify-content:center; }
        .login-logo::before { content:''; position:absolute; inset:-10px; border-radius:9999px; background:radial-gradient(circle, rgba(255,255,255,0.2), transparent 70%); filter:blur(10px); pointer-events:none; }
        .login-logo img { position:relative; width:80px; height:80px; object-fit:cover; border-radius:9999px; border:1px solid rgba(255,255,255,0.25); box-shadow:0 10px 34px rgba(0,0,0,0.55); }
        /* Logo ancho: entero, sin círculo ni borde (lo decide _ajustarLogoLogin).
           Altura fija y ancho automático: un SVG sin width/height propios
           (Punto Pilates) con los dos en auto se dibujaba de alto 0. */
        .login-logo.login-logo--ancho::before { inset:-14px -24px; }
        .login-logo.login-logo--ancho img { height:64px; width:auto; max-width:210px; object-fit:contain; border-radius:0; border:none; box-shadow:none; filter:drop-shadow(0 6px 18px rgba(0,0,0,0.55)); }
        .login-eyebrow { font-size:11px; color:rgba(255,255,255,0.55); font-weight:700; text-transform:uppercase; letter-spacing:0.24em; margin:0; }
        .login-nombre { font-size:1.55rem; line-height:1.15; font-weight:900; color:#fff; margin:0.4rem 0 0; }
        .login-slogan { font-size:0.82rem; color:rgba(255,255,255,0.6); margin:0.3rem 0 0; }
        .login-slogan:empty { display:none; }
        .login-tarjeta { border-radius:1.5rem; padding:1.4rem 1.3rem; background:rgba(14,14,18,0.82); backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px); border:1px solid rgba(255,255,255,0.1); box-shadow:0 24px 60px rgba(0,0,0,0.55); }
        .login-fila-ayuda { display:flex; align-items:center; gap:0.75rem; margin-top:0.55rem; }
        .login-link { background:transparent; border:none; padding:0.3rem 0.1rem; cursor:pointer; font-size:0.8rem; color:rgba(255,255,255,0.72); text-decoration:none; border-radius:0.4rem; transition:color .2s; }
        .login-link:hover { color:#fff; }
        .login-capslock { margin:0.5rem 0 0; font-size:0.78rem; color:#fcd34d; }
        /* El error es un aviso, no una línea roja chica. Sin `display` acá: la
           clase `hidden` de Tailwind tiene que poder ocultarlo (un id ganaría). */
        .login-error { margin:0.7rem 0 0; padding:0.6rem 0.75rem 0.6rem 2.1rem; border-radius:0.75rem; font-size:0.8rem; line-height:1.4; color:#fecaca; background:rgba(239,68,68,0.12) no-repeat 0.7rem 0.66rem / 16px 16px; border:1px solid rgba(239,68,68,0.35);
            background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23f87171'%3E%3Cpath d='M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24Zm-8 56a8 8 0 0 1 16 0v56a8 8 0 0 1-16 0Zm8 104a12 12 0 1 1 12-12a12 12 0 0 1-12 12Z'/%3E%3C/svg%3E"); }
        .login-btn-primario { width:100%; margin-top:1rem; padding:0.85rem; border-radius:0.85rem; font-size:0.9rem; font-weight:700; color:#0a0a0a; background:#fff; border:none; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:0.5rem; transition:transform .1s, background .2s, opacity .2s; }
        .login-btn-primario:hover:not(:disabled) { background:rgba(255,255,255,0.88); }
        .login-btn-primario:active:not(:disabled) { transform:scale(0.97); }
        .login-separador { display:flex; align-items:center; gap:0.7rem; margin-top:0.9rem; font-size:0.75rem; color:rgba(255,255,255,0.45); }
        .login-separador::before, .login-separador::after { content:''; flex:1; height:1px; background:rgba(255,255,255,0.1); }
        .login-btn-google { width:100%; margin-top:0.9rem; padding:0.8rem; border-radius:0.85rem; font-size:0.88rem; font-weight:600; color:#fff; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); cursor:pointer; display:flex; align-items:center; justify-content:center; gap:0.6rem; transition:background .2s, opacity .2s, transform .1s; }
        .login-btn-google:hover:not(:disabled) { background:rgba(255,255,255,0.1); }
        .login-btn-google:active:not(:disabled) { transform:scale(0.97); }
        /* Foco visible al navegar con teclado (antes los botones no tenían). */
        #loginOverlay button:focus-visible, #loginOverlay a:focus-visible { outline:2px solid rgba(255,255,255,0.85); outline-offset:2px; }
        .login-pie { text-align:center; margin-top:1.2rem; display:flex; flex-direction:column; align-items:center; gap:0.2rem; text-shadow:0 1px 3px rgba(0,0,0,0.8); }
        .login-pie p { margin:0; font-size:11px; color:rgba(255,255,255,0.66); letter-spacing:0.03em; }
        .login-pie strong { color:rgba(255,255,255,0.88); }
        .login-pie .login-link { font-size:0.8rem; }
        /* Pantallas bajas (iPhone SE, o cualquier celular con el teclado
           abierto): la marca se encoge para que el formulario no se vaya. */
        @media (max-height: 700px) {
            .login-marca { margin-bottom:1rem; }
            .login-logo { margin-bottom:0.65rem; }
            .login-logo img { width:64px; height:64px; }
            .login-logo.login-logo--ancho img { height:52px; }
            .login-nombre { font-size:1.35rem; }
            .login-tarjeta { padding:1.2rem 1.15rem; }
            .login-error { margin-top:0.55rem; padding-top:0.5rem; padding-bottom:0.5rem; background-position:0.7rem 0.56rem; }
        }
        /* Con un error a la vista no alcanzaba en el SE: menos aire arriba y abajo. */
        @media (max-width: 639.98px) and (max-height: 700px) {
            #loginOverlay {
                padding-top: max(14px, calc(env(safe-area-inset-top, 0px) + 10px));
                padding-bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 12px));
            }
        }
    