        :root {
            --primary: #14532d;
            --primary-dark: #0b3a1f;
            --accent: #16a34a;
            --accent-soft: rgba(22,163,74,0.12);
            --success: #22c55e;
            --danger: #dc2626;
            --purple: #7c3aed;
            --purple-soft: rgba(124,58,237,0.10);
            --bg: #f3f6f4;
            --card-bg: #ffffff;
            --input-bg: #ffffff;
            --text: #1c2620;
            --border: #dfe7e2;
            --badge-day-bg: #e3ece6;
            --badge-day-text: #3d5346;
            --radius-sm: 10px;
            --radius-md: 14px;
            --radius-lg: 20px;
            --shadow-sm: 0 1px 2px rgba(15,30,20,0.05), 0 1px 3px rgba(15,30,20,0.06);
            --shadow-md: 0 6px 16px rgba(15,30,20,0.08);
            --shadow-lg: 0 16px 40px rgba(15,30,20,0.20);
        }

        /* Variables para el Modo Oscuro / Alto Contraste */
        [data-theme="dark"] {
            --primary: #1f7a45;
            --primary-dark: #0c1f14;
            --accent: #34d399;
            --accent-soft: rgba(52,211,153,0.14);
            --success: #4ade80;
            --danger: #f87171;
            --purple: #a78bfa;
            --purple-soft: rgba(167,139,250,0.14);
            --bg: #0d1512;
            --card-bg: #17221c;
            --input-bg: #101a15;
            --text: #eaf3ee;
            --border: #2a3a31;
            --badge-day-bg: #2a3a31;
            --badge-day-text: #eaf3ee;
            --shadow-sm: 0 1px 2px rgba(0,0,0,0.25), 0 1px 3px rgba(0,0,0,0.3);
            --shadow-md: 0 6px 16px rgba(0,0,0,0.35);
            --shadow-lg: 0 16px 40px rgba(0,0,0,0.55);
        }

        * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -webkit-user-select: none; user-select: none; }
        html, body { overflow-anchor: none; } /* evita que el navegador "corrija" el scroll cuando cambia la altura del contenido tras un render tardío (gráficos, listas, etc.) */
        body { background-color: var(--bg); color: var(--text); padding-bottom: 30px; transition: background-color 0.3s, color 0.3s; -webkit-tap-highlight-color: transparent; }
        button, input, select, textarea { font-family: inherit; }
        button { transition: transform 0.12s ease, opacity 0.12s ease, background-color 0.15s ease, box-shadow 0.15s ease; }
        a:focus-visible, button:focus-visible, input:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

        /* v6.200.0 — FIX: en Android edge-to-edge (obligatorio desde
           Android 15, y ya el comportamiento por defecto de Capacitor en
           dispositivos más nuevos), el WebView ocupa toda la pantalla
           por detrás de la barra de estado del sistema — así que la
           cabecera, al ser lo primero que se pinta, quedaba literalmente
           debajo del reloj/batería/iconos del móvil en vez de empezar
           por debajo de ellos. padding-top suma env(safe-area-inset-top)
           (0 en dispositivos sin recorte/notch, el alto real de la barra
           de estado en el resto) para que el contenido de la cabecera
           empiece siempre justo debajo, se vea el dispositivo que se
           vea. */
        header { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: white; padding: calc(14px + env(safe-area-inset-top)) 16px 14px 16px; box-shadow: 0 4px 14px rgba(0,0,0,0.18); display: flex; align-items: center; justify-content: space-between; gap: 10px; position: relative; z-index: 5; }
        h1 { font-size: 1.05rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; text-align: left; flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }

        /* Botón de Modo Oscuro */
        .theme-toggle { flex: 0 0 auto; background: rgba(255,255,255,0.16); border: 1px solid rgba(255,255,255,0.25); color: white; padding: 6px 12px; border-radius: 20px; font-size: 0.9rem; cursor: pointer; font-weight: bold; white-space: nowrap; }
        .theme-toggle:active { background: rgba(255,255,255,0.32); transform: scale(0.96); }

        .container { padding: 15px; max-width: 500px; margin: 0 auto; }


        /* En horizontal el contenedor se quedaba anclado a 500px y dejaba huecos
           enormes a los lados en el móvil; en landscape lo ensanchamos. */
        @media (orientation: landscape) {
            .container { max-width: 900px; }
        }

        /* PANTALLA INICIAL / MENÚ */
        .menu-grid { display: grid; grid-template-columns: 1fr; gap: 14px; margin-top: 20px; }

        /* CARRUSEL DEL MENÚ (2 páginas: Plan+Partidos / Ficha+Distancias+Estadísticas) */
        .menu-carousel-wrap { margin-top: 20px; }
        /* v6.211 — la altura se fija por JS (adjustMenuCarouselHeight) a la de la
           página activa, para que las páginas más cortas del carrusel no hereden
           el hueco vacío de la más alta (antes: al ser flex en fila, las 3
           páginas se estiraban todas a la altura de la más alta). align-items:
           flex-start evita que, mientras la transición de altura está en curso,
           una página se recorte o se centre raro. */
        .menu-carousel-viewport { overflow: hidden; transition: height 0.28s cubic-bezier(0.4, 0, 0.2, 1); }
        .menu-carousel-track { display: flex; align-items: flex-start; transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1); }
        .menu-carousel-page { flex: 0 0 100%; min-width: 100%; display: flex; flex-direction: column; gap: 14px; box-sizing: border-box; }
        .menu-carousel-dots { display: flex; justify-content: center; align-items: center; gap: 9px; margin-top: 16px; }
        .menu-carousel-dots .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); cursor: pointer; transition: background 0.2s ease, transform 0.2s ease; border: none; padding: 0; }
        .menu-carousel-dots .dot.active { background: var(--accent); transform: scale(1.35); }
        .menu-carousel-hint { text-align: center; font-size: 0.7rem; opacity: 0.5; margin-top: 6px; }
        .btn-menu { background: var(--card-bg); border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius-lg); padding: 22px 24px; font-size: 1.05rem; font-weight: 700; color: var(--text); cursor: pointer; text-align: left; box-shadow: var(--shadow-sm); transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease; }
        .btn-menu:active { transform: scale(0.98); background: var(--accent-soft); box-shadow: var(--shadow-sm); }
        .btn-back { background: var(--card-bg); color: var(--text); border: 1px solid var(--border); padding: 10px 16px; border-radius: var(--radius-sm); font-weight: 700; font-size: 0.85rem; cursor: pointer; margin-bottom: 15px; display: inline-block; box-shadow: var(--shadow-sm); }
        .btn-back:active { background: var(--border); transform: scale(0.97); }

        /* SECCIONES Y TARJETAS */
        .section-title { font-size: 1.05rem; color: var(--accent); margin: 25px 0 10px 0; font-weight: 800; border-bottom: 2px solid var(--border); padding-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }

        /* Botones de navegación ("← Atrás" / "🏠 Menú") — solo se muestran en
           la versión web (PC / navegador de iPhone, cualquier navegador sin
           la app instalada, etc.), porque ahí no existe el botón/gesto
           físico de "atrás" que sí tiene la app Android (ver
           setupAndroidBackButton en 09-dashboard-save-round.js). Sin estos
           botones, en web no había forma de volver salvo cerrando y
           reabriendo la pestaña. En la APK nunca se muestran: el
           comportamiento nativo (gesto/botón físico de atrás) no cambia.
           v6.213 — FIX de Andrés: eran "position: fixed" con top/left fijos,
           así que en la versión web se quedaban siempre pegados a la esquina
           superior de la ventana por encima de TODO, incluida la cabecera
           verde (⛳ Green Tracker Pro / usuario / tema) — cuando la página
           estaba arriba del todo (el caso normal nada más entrar), los
           botones tapaban el logo. Ahora usan "position: sticky": al cargar
           la pantalla se quedan en su sitio normal, justo debajo de la
           cabecera (sin pisarla), y solo se "pegan" a los 14px de arriba de
           la ventana cuando el usuario baja el scroll lo bastante como para
           que le tocara salirse de la pantalla — momento en el que la
           cabecera (que va ANTES en el documento) ya lleva rato fuera de
           vista, así que nunca vuelven a solaparse. */
        #web_nav_btns {
            position: sticky;
            top: 14px;
            z-index: 50;
            display: flex;
            gap: 8px;
            margin-bottom: 14px;
        }
        #web_nav_btns.hidden { display: none; }
        #web_nav_btns button {
            background: var(--card-bg);
            color: var(--accent);
            border: 1px solid var(--border);
            border-radius: 999px;
            padding: 9px 16px;
            font-size: 0.85rem;
            font-weight: 700;
            box-shadow: var(--shadow-sm);
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        #web_nav_btns button:active { transform: scale(0.96); background: var(--accent-soft); }
        @media (min-width: 700px) {
            #web_nav_btns { top: 18px; }
            #web_nav_btns button { padding: 10px 18px; font-size: 0.9rem; }
        }
        .section-title:has(.btn-edit-distances) { display: flex; align-items: center; justify-content: space-between; }
        .btn-edit-distances { background: var(--accent-soft); color: var(--accent); border: none; border-radius: 20px; padding: 5px 13px; font-size: 0.7rem; font-weight: bold; text-transform: none; letter-spacing: normal; cursor: pointer; }
        .btn-edit-distances:active { opacity: 0.7; transform: scale(0.96); }
        .distance-input { width: 55px; padding: 5px 6px; border-radius: var(--radius-sm); border: 1px solid var(--accent); background: var(--input-bg); color: var(--text); font-size: 0.82rem; font-weight: 600; }
        .note-input { width: 100%; padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--input-bg); color: var(--text); font-size: 0.88rem; font-family: inherit; }
        .note-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

        /* FICHA DE JUGADOR */
        .ficha-field label { display: block; font-size: 0.75rem; font-weight: 700; opacity: 0.7; margin-bottom: 6px; }
        .ficha-edad-badge { font-weight: 600; opacity: 0.6; font-size: 0.78rem; white-space: nowrap; flex-shrink: 0; }
        .ficha-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
        .ficha-result { margin-top: 14px; padding: 14px; border-radius: var(--radius-md); background: var(--purple-soft); border-left: 4px solid var(--purple); font-size: 0.9rem; color: var(--text); text-align: center; }
        .ficha-stats-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
        .ficha-stat { text-align: center; }
        .ficha-stat-num { font-size: 1.6rem; font-weight: 800; color: var(--accent); }
        .ficha-stat-label { font-size: 0.7rem; opacity: 0.65; text-transform: uppercase; letter-spacing: 0.3px; margin-top: 2px; }
        .export-btns { display: flex; gap: 10px; margin-top: 12px; margin-bottom: 20px; }
        .btn-export { flex: 1; padding: 12px 0; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--card-bg); color: var(--text); font-weight: 700; font-size: 0.82rem; cursor: pointer; box-shadow: var(--shadow-sm); }
        .btn-export:active { opacity: 0.75; transform: scale(0.98); }

        .app-footer { text-align: center; font-size: 0.72rem; opacity: 0.5; margin: 25px 0 10px 0; }

        /* DASHBOARD (resumen rápido arriba del Menú) */
        .dashboard-wrap { margin-bottom: 22px; }
        .dashboard-title { font-size: 1.05rem; font-weight: 800; color: var(--accent); margin-bottom: 10px; letter-spacing: 0.3px; }
        .dashboard-quote-card { background: linear-gradient(135deg, var(--accent-soft), transparent 70%), var(--card-bg); border-left: 4px solid var(--accent); border-radius: var(--radius-md); padding: 13px 15px; margin-bottom: 12px; box-shadow: var(--shadow-sm); }
        .dashboard-quote-text { font-size: 0.86rem; font-style: italic; line-height: 1.4; }
        .dashboard-quote-author { font-size: 0.74rem; opacity: 0.65; margin-top: 6px; text-align: right; font-weight: 600; }
        .dashboard-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
        .dash-card-full { grid-column: 1 / -1; }
        .dash-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 11px 13px; box-shadow: var(--shadow-sm); }
        .dash-card-clickable { cursor: pointer; position: relative; transition: transform 0.12s ease, box-shadow 0.12s ease; }
        .dash-card-clickable:active { transform: scale(0.97); box-shadow: var(--shadow-sm); }
        .dash-card-clickable::after { content: '›'; position: absolute; top: 9px; right: 11px; font-size: 0.9rem; font-weight: 900; opacity: 0.3; color: var(--accent); }
        .dash-highlight-flash { animation: dashHighlightFlash 1.7s ease; border-radius: var(--radius-md); }
        @keyframes dashHighlightFlash {
            0% { box-shadow: 0 0 0 3px var(--accent); background-color: var(--accent-soft); }
            70% { box-shadow: 0 0 0 3px var(--accent); background-color: var(--accent-soft); }
            100% { box-shadow: 0 0 0 0px transparent; background-color: transparent; }
        }
        @keyframes dashDetailHighlight {
            0% { box-shadow: 0 0 0 0 rgba(22,163,74,0.45); }
            60% { box-shadow: 0 0 0 8px rgba(22,163,74,0); }
            100% { box-shadow: 0 0 0 0 rgba(22,163,74,0); }
        }
        .dash-detail-highlight { animation: dashDetailHighlight 1.4s ease-out 1; border-radius: var(--radius-sm); }
        .dash-card-wide { grid-column: 1 / -1; }
        .dash-label { font-size: 0.68rem; opacity: 0.62; text-transform: uppercase; letter-spacing: 0.4px; font-weight: 700; margin-bottom: 4px; }
        .dash-value { font-size: 1.05rem; font-weight: 800; color: var(--text); line-height: 1.25; }
        .dash-value-sub { font-size: 0.72rem; opacity: 0.65; margin-top: 2px; font-weight: 500; }
        .dash-trend-good { color: var(--success); }
        .dash-trend-bad { color: var(--danger); }
        .dash-trend-neutral { color: var(--text); opacity: 0.8; }
        .dash-score-num { font-size: 1.5rem; font-weight: 900; }
        /* Estrellas de progreso (🏅 Nivel): 10 estrellas, se rellenan entera o
           mitad según el índice global de Progreso y Precisión (0-10) — o sea,
           cuánto te queda dentro de tu escalón actual para subir al siguiente. */
        .nivel-stars-row { display: flex; gap: 1px; margin-top: 5px; }
        .nivel-star { position: relative; display: inline-block; width: 13px; height: 13px; font-size: 13px; line-height: 1; color: var(--border); }
        .nivel-star-fill { position: absolute; top: 0; left: 0; overflow: hidden; color: #f2b400; white-space: nowrap; }
        .dash-streak-card { border-left: 4px solid var(--accent); margin-bottom: 12px; }
        .dash-advice-card { border-left: 4px solid var(--purple); }
        .dash-advice-text { font-size: 0.82rem; line-height: 1.45; opacity: 0.9; }
        .dash-coach-card { border-left: 4px solid var(--success); }
        .dash-coach-row { margin-bottom: 8px; }
        .dash-coach-row:last-child { margin-bottom: 0; }
        .dash-coach-q { font-size: 0.72rem; font-weight: 700; opacity: 0.7; margin-bottom: 2px; }
        .dash-coach-a { font-size: 0.85rem; line-height: 1.4; }
        .dash-coach-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
        .dash-collapsible-header { cursor: pointer; user-select: none; }
        .dash-collapsible-chevron { display: inline-block; font-size: 0.8rem; opacity: 0.6; transition: transform 0.2s ease; }
        .dash-collapsible-chevron.open { transform: rotate(90deg); }
        .section-title.dash-collapsible-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
        .btn-dash-refresh { background: var(--accent-soft); color: var(--accent); border: none; border-radius: 20px; padding: 5px 11px; font-size: 0.7rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
        .btn-dash-refresh:active { opacity: 0.7; transform: scale(0.95); }
        .btn-dash-refresh:disabled { opacity: 0.5; }
        .dash-coach-date { font-size: 0.68rem; opacity: 0.5; margin-top: 6px; }
        .dash-empty { font-size: 0.8rem; opacity: 0.6; font-style: italic; }

        /* PANTALLA DE ACCESO (login con Google) */
        .auth-gate { position: fixed; inset: 0; z-index: 999; background: radial-gradient(circle at 30% 15%, #1c6b3f, transparent 55%), linear-gradient(160deg, #0f2e1c, #071711); display: flex; align-items: center; justify-content: center; padding: 24px; }
        .auth-gate-box { background: var(--card-bg); border-radius: var(--radius-lg); padding: 36px 28px; max-width: 360px; width: 100%; text-align: center; box-shadow: var(--shadow-lg); }
        .auth-gate-logo { font-size: 3rem; margin-bottom: 6px; }
        .auth-gate-box h1 { font-size: 1.3rem; margin: 0 0 10px 0; color: var(--accent); text-transform: none; }
        .auth-gate-box p { font-size: 0.85rem; opacity: 0.75; line-height: 1.5; margin-bottom: 22px; }
        .btn-google-signin { width: 100%; padding: 13px; border-radius: var(--radius-md); border: 1px solid var(--border); background: #fff; color: #3c4043; font-weight: 700; font-size: 0.92rem; display: flex; align-items: center; justify-content: center; gap: 10px; cursor: pointer; box-shadow: var(--shadow-sm); }
        .btn-google-signin:active { transform: scale(0.98); }
        .auth-gate-error { margin-top: 14px; margin-bottom: 0; color: var(--danger); font-size: 0.78rem; }
        .account-info { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; color: white; }
        .account-icon { flex-shrink: 0; }

        /* PANTALLA DE CONSENTIMIENTO DE PRIVACIDAD (RGPD/LOPD) */
        .consent-gate { position: fixed; inset: 0; z-index: 1000; background: radial-gradient(circle at 30% 15%, #1c6b3f, transparent 55%), linear-gradient(160deg, #0f2e1c, #071711); display: flex; align-items: center; justify-content: center; padding: 20px; }
        .consent-gate-box { background: var(--card-bg); border-radius: var(--radius-lg); padding: 28px 22px; max-width: 420px; width: 100%; box-shadow: var(--shadow-lg); }
        .consent-gate-box h2 { font-size: 1.1rem; margin: 0 0 12px 0; color: var(--accent); text-align: center; }
        .consent-text { max-height: 42vh; overflow-y: auto; font-size: 0.78rem; line-height: 1.55; opacity: 0.9; text-align: left; border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 14px; margin-bottom: 16px; }
        .consent-text p { margin: 0 0 10px 0; }
        .consent-text p:last-child { margin-bottom: 0; }
        .consent-text b { opacity: 1; }
        .consent-checkbox-row { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 18px; font-size: 0.8rem; line-height: 1.4; text-align: left; }
        .consent-checkbox-row input[type="checkbox"] { width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; accent-color: var(--accent); }
        .consent-btn-row { display: flex; flex-direction: column; gap: 10px; }
        .btn-consent-accept { width: 100%; padding: 13px; border-radius: var(--radius-md); border: none; background: var(--accent); color: #fff; font-weight: 700; font-size: 0.9rem; cursor: pointer; box-shadow: var(--shadow-sm); }
        .btn-consent-accept:disabled { opacity: 0.4; cursor: not-allowed; }
        .btn-consent-decline { width: 100%; padding: 10px; border-radius: var(--radius-md); border: 1px solid var(--border); background: transparent; color: var(--text); font-weight: 600; font-size: 0.82rem; cursor: pointer; opacity: 0.75; }
        .btn-signout { background: none; border: 1px solid rgba(255,255,255,0.5); border-radius: var(--radius-sm); padding: 4px 9px; font-size: 0.7rem; color: white; cursor: pointer; opacity: 0.9; }

        /* WIDGET DE VIENTO/TEMPERATURA (Open-Meteo, sin API key) */
        .weather-widget { display: flex; align-items: center; gap: 10px; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 13px; margin-bottom: 10px; font-size: 0.85rem; font-weight: 600; color: var(--text); box-shadow: var(--shadow-sm); }
        .weather-sep { opacity: 0.4; }
        .weather-label { font-size: 0.68rem; font-weight: 600; opacity: 0.55; text-transform: uppercase; letter-spacing: 0.3px; margin-bottom: 2px; }
        #weather_content { flex: 1; min-width: 0; }
        .weather-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
        .weather-slot { display: flex; align-items: center; gap: 5px; }
        .weather-slot-label { font-size: 0.68rem; opacity: 0.6; font-weight: 700; text-transform: uppercase; }
        .btn-weather-refresh { flex: 0 0 auto; background: var(--accent-soft); border: none; color: var(--accent); width: 34px; height: 34px; border-radius: 50%; font-size: 1rem; cursor: pointer; }
        .btn-weather-refresh:active { opacity: 0.7; transform: scale(0.92); }
        .btn-weather-refresh.spinning { animation: spin 0.8s linear; }
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

        /* TARJETA DE RECORDATORIOS + INTERRUPTOR */
        .reminder-card { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 13px 15px; margin-bottom: 15px; box-shadow: var(--shadow-sm); }
        .reminder-title { font-size: 0.88rem; font-weight: 700; color: var(--text); }
        .reminder-desc { font-size: 0.72rem; opacity: 0.6; margin-top: 2px; }
        .switch { position: relative; display: inline-block; width: 46px; height: 26px; flex-shrink: 0; }
        .switch input { opacity: 0; width: 0; height: 0; }
        .switch-slider { position: absolute; cursor: pointer; inset: 0; background-color: var(--border); border-radius: 26px; transition: 0.2s; }
        .switch-slider::before { position: absolute; content: ""; height: 20px; width: 20px; left: 3px; bottom: 3px; background-color: white; border-radius: 50%; transition: 0.2s; box-shadow: 0 1px 3px rgba(0,0,0,0.25); }
        .switch input:checked + .switch-slider { background-color: var(--success); }
        .switch input:checked + .switch-slider::before { transform: translateX(20px); }
        .card { background: var(--card-bg); border-radius: var(--radius-md); padding: 16px; margin-bottom: 15px; box-shadow: var(--shadow-sm); border: 1px solid var(--border); }

        .uh-card { background: var(--card-bg); border-radius: var(--radius-md); border: 1px solid var(--border); margin-bottom: 10px; overflow: hidden; }
        .uh-header { padding: 12px 14px; cursor: pointer; display: flex; flex-direction: column; gap: 4px; }
        .uh-header-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
        .uh-header-left { display: flex; align-items: center; gap: 8px; }
        .uh-date { font-weight: 700; font-size: 0.85rem; }
        .uh-note { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 0.95rem; }
        .uh-chevron { opacity: 0.4; font-size: 0.8rem; transition: transform 0.15s ease; }
        .uh-card.uh-open .uh-chevron { transform: rotate(180deg); }
        .uh-summary-line { font-size: 0.76rem; opacity: 0.7; display: flex; align-items: center; gap: 5px; }
        .uh-detail { display: none; padding: 0 14px 14px; border-top: 1px solid var(--border); }
        .uh-card.uh-open .uh-detail { display: block; padding-top: 12px; }
        .uh-detail-section { margin-bottom: 12px; }
        .uh-detail-title { font-size: 0.72rem; font-weight: 700; opacity: 0.6; text-transform: uppercase; margin-bottom: 6px; }
        .uh-detail-row { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; font-size: 0.82rem; border-bottom: 1px solid var(--border); }
        .uh-detail-row:last-child { border-bottom: none; }
        .uh-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

        .goals-month-label { font-size: 0.78rem; opacity: 0.6; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
        .goal-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--border); }
        .goal-row:last-of-type { border-bottom: none; }
        .goal-check-label { display: flex; align-items: center; gap: 10px; cursor: pointer; flex: 1; font-size: 0.9rem; }
        .goal-check-label input[type="checkbox"] { width: 19px; height: 19px; flex-shrink: 0; accent-color: var(--success); cursor: pointer; }
        .goal-row.goal-done .goal-check-label span { text-decoration: line-through; opacity: 0.5; }
        .goal-progress { text-align: right; font-size: 0.72rem; opacity: 0.6; margin-top: 8px; font-weight: 700; }
        .goal-auto-badge { display: inline-flex; align-items: center; justify-content: center; width: 18px; }
        .achievement-date { font-size: 0.7rem; opacity: 0.55; white-space: nowrap; flex-shrink: 0; }
        .goal-add-row { display: flex; gap: 8px; margin-top: 12px; }
        .goal-add-row input { flex: 1; padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--input-bg, var(--card-bg)); color: var(--text); font-size: 0.85rem; }
        .goal-add-row button { flex-shrink: 0; padding: 10px 16px; border-radius: var(--radius-sm); border: none; background: var(--accent); color: #fff; font-weight: 700; font-size: 0.85rem; cursor: pointer; }
        .goal-add-row button:active { transform: scale(0.96); }

        .badges-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; }
        .badge-tile { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 12px 6px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--input-bg, var(--card-bg)); cursor: pointer; }
        .badge-tile.badge-locked { opacity: 0.45; filter: grayscale(1); }
        .badge-tile.badge-earned { opacity: 1; filter: none; border-color: #d69e2e; box-shadow: 0 0 0 1px rgba(214,158,46,0.25); }
        .badge-icon { position: relative; font-size: 1.7rem; line-height: 1; margin-bottom: 6px; }
        .badge-tier-icon { position: absolute; bottom: -6px; right: -10px; font-size: 0.85rem; }
        .badge-name { font-size: 0.72rem; font-weight: 700; line-height: 1.2; margin-bottom: 6px; overflow-wrap: break-word; hyphens: auto; }
        .badge-progress-track { width: 100%; height: 5px; border-radius: 999px; background: var(--border); overflow: hidden; margin-bottom: 4px; }
        .badge-progress-fill { height: 100%; background: #d69e2e; border-radius: 999px; }
        .badge-tile.badge-locked .badge-progress-fill { background: #a0aec0; }
        .badge-progress-txt { font-size: 0.62rem; opacity: 0.65; font-weight: 600; }
        .trend-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 0.85rem; line-height: 1.35; }
        .trend-row:last-of-type { border-bottom: none; }
        .trend-icon { flex-shrink: 0; font-size: 1rem; }
        .trend-row.dash-trend-good .trend-text { color: var(--success); }
        .trend-row.dash-trend-bad .trend-text { color: var(--danger); }
        .card-green { background: linear-gradient(135deg, var(--accent-soft), transparent 65%), var(--card-bg); border-left: 4px solid var(--success); }
        #green_blocks_wrap.green-unavailable { opacity: 0.45; pointer-events: none; filter: grayscale(60%); }
        /* v6.104: checkbox "quiero entrenar este ejercicio" en la cabecera de cada
           bloque de Green (colapsable). Cuando se desmarca, el bloque entero se
           atenúa e ignora los toques, igual que "Green no disponible" pero solo
           para ESE ejercicio en vez de los 4 a la vez. */
        .exercise-want-check { display: inline-flex; align-items: center; margin-right: 2px; }
        .exercise-want-check input { width: 17px; height: 17px; accent-color: var(--success); cursor: pointer; }
        .card-green.exercise-skipped { opacity: 0.45; filter: grayscale(55%); }
        .card-green.exercise-skipped .dash-collapsible-body { pointer-events: none; }
        .card-green > h2.dash-collapsible-header { cursor: pointer; user-select: none; align-items: center; gap: 6px; }
        .card-green > h2.dash-collapsible-header .dash-collapsible-chevron { margin-left: auto; flex: 0 0 auto; }
        /* v6.104: selector de campo "propio" de una sección (Green / Entreno del
           mes), mismo estilo compacto que ya usaba solo Cancha. */
        .section-campo-picker { padding: 10px 12px; margin-bottom: 10px; }
        .section-campo-picker label { font-size: 0.72rem; font-weight: 700; opacity: 0.7; display: block; margin-bottom: 6px; }

        /* CAJA DE PLAN DE HOYOS CON RIESGO */
        .risk-box { margin-top: 12px; padding: 13px 15px; border-radius: var(--radius-md); border-left: 4px solid var(--danger); background: linear-gradient(135deg, rgba(220,38,38,0.09), transparent 65%), var(--card-bg); font-size: 0.82rem; line-height: 1.5; }
        .risk-box b { color: var(--danger); }
        .risk-box ul { margin: 6px 0 0 18px; padding: 0; }
        .risk-box li { margin-bottom: 4px; }
        h2 { font-size: 0.95rem; color: var(--accent); margin-bottom: 10px; display: flex; justify-content: space-between; border-bottom: 1px solid var(--border); padding-bottom: 5px; }
        .time-badge { font-size: 0.75rem; background: #fde8cc; color: #b45309; padding: 4px 11px; border-radius: 20px; font-weight: bold; border: none; cursor: pointer; transition: all 0.2s; font-family: inherit; }
        .btn-reset-block { font-size: 0.85rem; background: var(--border); color: var(--text); padding: 4px 10px; border-radius: 20px; font-weight: bold; border: none; cursor: pointer; opacity: 0.75; }
        .btn-reset-block:active { opacity: 1; transform: scale(0.93); }
        .time-badge:active { transform: scale(0.93); }
        .time-badge.timer-active { background: var(--primary); color: white; animation: pulseTimer 1s ease-in-out infinite; }
        .time-badge.timer-done { background: var(--danger); color: white; animation: shakeTimer 0.4s ease-in-out 3; }
        @keyframes pulseTimer { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
        @keyframes shakeTimer { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

        .desc { font-size: 0.85rem; color: var(--text); opacity: 0.8; margin-bottom: 12px; line-height: 1.3; }
        .help-note { font-size: 0.75rem; color: var(--text); opacity: 0.6; text-align: center; margin-top: -5px; margin-bottom: 10px; font-style: italic; }
        /* Este help-note en concreto va justo debajo de una tarjeta con borde (risk-box o card-green),
           no debajo de un título como el resto de help-note, así que el margen negativo de arriba
           hacía que se solapara visualmente con el borde inferior de esa tarjeta. */
        #lbl_fin_sesion { margin-top: 14px; }
        /* Mismo caso que #lbl_fin_sesion: estos dos help-note van debajo del
           botón "Comenzar Partido" (btn-save), no debajo de un section-title,
           así que el margen negativo por defecto hacía que el primero se
           solapara con el botón. */
        #btn_comenzar_partido_help1, #btn_comenzar_partido_help2 { margin-top: 8px; }

        /* BOTONES DE SELECCIÓN DE DÍA */
        .teacher-style-list { display: flex; flex-direction: column; gap: 8px; }
        .teacher-style-card { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; cursor: pointer; background: var(--card-bg); transition: border-color 0.15s ease, background 0.15s ease; }
        .teacher-style-card:active { transform: scale(0.99); }
        .teacher-style-card.active { border-color: var(--accent); background: var(--accent-soft); }
        .teacher-style-card-title { font-size: 0.85rem; font-weight: 700; color: var(--text); display: flex; align-items: center; justify-content: space-between; gap: 8px; }
        .teacher-style-card-check { font-size: 0.68rem; font-weight: 700; color: var(--accent); white-space: nowrap; }
        .teacher-style-card-desc { font-size: 0.72rem; opacity: 0.7; margin-top: 4px; line-height: 1.35; }
        .day-selector { margin-bottom: 15px; display: flex; gap: 8px; }
        .day-btn { flex: 1; padding: 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card-bg); font-size: 0.8rem; font-weight: bold; cursor: pointer; color: var(--text); opacity: 0.7; }
        .day-btn.active { background: var(--primary); color: white; border-color: var(--primary); opacity: 1; box-shadow: var(--shadow-sm); }
        /* v6.105 — Barra de resumen ("✅ Cancha lista · ⏳ Green: 2/4 ejercicios")
           arriba del todo de la Ficha de Entrenamiento, para ver de un vistazo
           qué falta sin tener que desplegar Cancha ni Green. */
        .training-summary-bar { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; padding: 9px 12px; margin-bottom: 15px; border-radius: var(--radius-sm); background: var(--card-bg); border: 1px solid var(--border); font-size: 0.78rem; font-weight: 700; box-shadow: var(--shadow-sm); }
        .training-summary-sep { opacity: 0.35; font-weight: 400; }
        .training-summary-clickable { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
        .training-summary-clickable:active { opacity: 0.6; }

        /* CONTADORES INTELIGENTES TÁCTILES */
        .counter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
        .btn-counter { padding: 15px 10px; border: none; border-radius: var(--radius-md); font-size: 0.9rem; font-weight: bold; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; }

        /* Ajuste de colores según tema para los contadores */
        .btn-success { background-color: var(--accent-soft); color: var(--success); border: 2px solid var(--success); }
        .btn-success:active { background-color: rgba(34,197,94,0.25); transform: scale(0.97); }
        .btn-danger { background-color: rgba(220,38,38,0.10); color: var(--danger); border: 2px solid var(--danger); }
        .btn-danger:active { background-color: rgba(220,38,38,0.25); transform: scale(0.97); }
        .score-val { font-size: 1.6rem; margin-top: 4px; font-weight: 800; }

        .streak-container { text-align: center; padding: 10px 0; }
        .streak-display { font-size: 2.5rem; font-weight: bold; color: var(--accent); margin: 5px 0; }
        .streak-btns { display: grid; grid-template-columns: 2fr 1fr; gap: 10px; }
        .streak-progress-info { display: flex; justify-content: space-between; margin-top: 12px; font-size: 0.78rem; opacity: 0.8; }
        .done-check { display: flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 0.78rem; opacity: 0.7; cursor: pointer; user-select: none; }
        .done-check input { width: 16px; height: 16px; accent-color: var(--success); cursor: pointer; }
        .btn-main { background-color: var(--success); color: white; padding: 13px; border: none; border-radius: var(--radius-md); font-weight: bold; font-size: 1rem; box-shadow: var(--shadow-sm); }
        .btn-main:active { background-color: #16a34a; transform: scale(0.98); }
        .btn-reset { background-color: var(--danger); color: white; padding: 13px; border: none; border-radius: var(--radius-md); font-weight: bold; font-size: 0.9rem; box-shadow: var(--shadow-sm); }
        .btn-reset:active { background-color: #b91c1c; transform: scale(0.98); }

        .btn-save { background-color: var(--accent); color: white; width: 100%; padding: 15px; border: none; border-radius: var(--radius-md); font-weight: bold; font-size: 1rem; margin-top: 15px; box-shadow: var(--shadow-sm); }
        .btn-save:active { transform: scale(0.98); }
        .btn-save:disabled { background-color: var(--border); color: var(--text); opacity: 0.5; cursor: not-allowed; }

        /* HISTÓRICO TABLA */
        .table-wrapper { width: 100%; overflow-x: auto; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); margin-top: 15px; box-shadow: var(--shadow-sm); }
        table { width: 100%; border-collapse: collapse; text-align: left; font-size: 0.85rem; }
        th { background-color: var(--badge-day-bg); color: var(--text); padding: 12px 10px; font-weight: 700; }
        /* La tabla de Histórico de Sesiones de Green tiene cabeceras de más
           de una palabra (Vel. OK, Presión 1m): con width:100% el navegador
           las partía en 2 líneas para intentar caber en pantallas móviles.
           Con un ancho mínimo y sin salto de línea, se ve igual de bien y
           simplemente aparece scroll horizontal si no cabe entera. */
        #history_table th { white-space: nowrap; }
        td { padding: 12px 10px; border-bottom: 1px solid var(--border); color: var(--text); }
        tr:last-child td { border-bottom: none; }

        /* MINI-TABLAS DE PLAN DE CANCHA */
        .plan-table-wrap { margin-top: 10px; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
        .plan-table-title { background: var(--badge-day-bg); color: var(--text); font-size: 0.78rem; font-weight: 700; padding: 7px 10px; text-transform: uppercase; letter-spacing: 0.3px; }

        /* IMPORTAR SESIÓN DE SWINGSYNC (CSV) */
        .btn-import-swingsync { width: 100%; padding: 12px 0; margin: 10px 0; border-radius: var(--radius-md); border: 1.5px dashed var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; font-size: 0.85rem; cursor: pointer; }
        .btn-import-swingsync:active { background: rgba(22,163,74,0.22); transform: scale(0.99); }
        .cancha-import-card { padding: 13px 16px; }
        .cancha-import-header { display: flex; align-items: center; justify-content: space-between; font-size: 0.82rem; font-weight: 700; margin-bottom: 10px; color: var(--text); }
        #cancha_import_filename { font-weight: 400; opacity: 0.55; font-size: 0.72rem; }
        .btn-clear-import { background: var(--border); color: var(--text); border: none; width: 24px; height: 24px; border-radius: 50%; cursor: pointer; font-size: 0.75rem; }

        /* EVALUACIÓN DE SESIÓN CON IA */
        .btn-ai-eval { width: 100%; padding: 15px 0; margin: 15px 0 10px 0; border-radius: var(--radius-md); border: none; background: linear-gradient(135deg, var(--purple), var(--accent)); color: white; font-weight: 800; font-size: 0.9rem; cursor: pointer; box-shadow: 0 4px 14px rgba(124,58,237,0.28); }
        .btn-ai-eval:active { opacity: 0.88; transform: scale(0.98); }
        .btn-ai-eval:disabled { opacity: 0.6; }
        .ai-report-card { border-left: 4px solid var(--purple); }
        .ai-report-header { display: flex; align-items: center; justify-content: space-between; font-weight: 800; font-size: 0.9rem; margin-bottom: 10px; color: var(--text); }
        .ai-report-score { background: var(--purple); color: white; padding: 3px 11px; border-radius: 20px; font-size: 0.78rem; font-weight: 800; }
        .ai-report-text { font-size: 0.85rem; line-height: 1.55; white-space: pre-wrap; color: var(--text); }
        .ai-report-title { font-weight: 800; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--purple); margin: 12px 0 2px; }
        .ai-report-title:first-child { margin-top: 0; }
        .ai-report-list { margin: 2px 0 8px; padding-left: 22px; white-space: normal; }
        .ai-report-list li { margin-bottom: 4px; }
        .ai-report-divider { border: none; border-top: 1px solid var(--border); margin: 14px 0; opacity: 0.6; }
        .plan-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
        .plan-table th { text-align: left; padding: 7px 10px; font-weight: 700; color: var(--accent); border-bottom: 1px solid var(--border); }
        .plan-table td { padding: 7px 10px; border-bottom: 1px solid var(--border); color: var(--text); }
        .plan-table tr:last-child td { border-bottom: none; }
        .badge-day { background: var(--badge-day-bg); color: var(--badge-day-text); padding: 4px 9px; border-radius: 20px; font-weight: bold; font-size: 0.72rem; text-transform: uppercase; }
        .btn-note-icon { background: none; border: none; color: var(--text); cursor: pointer; font-size: 0.8rem; padding: 0 0 0 4px; vertical-align: middle; }
        .real-day-note { font-size: 0.65rem; opacity: 0.55; font-style: italic; margin-top: 2px; }
        /* v6.134 — limpieza: aquí había un segundo bloque .badge-yes/.badge-no/
           .badge-consist-* con colores fijos (#15803d, #b91c1c, etc.).
           Quedó muerto desde el fix de contraste en modo oscuro (ver
           comentario junto al bloque real, más abajo, que ya usa
           var(--success)/var(--danger)) — el bloque de abajo, por ir
           después en el fichero, siempre ganaba la cascada, así que este
           nunca se aplicaba de verdad. Se borra para no confundir a quien
           lo lea pensando que estos son los colores vigentes. */
        .consist-subtext { font-size: 0.62rem; opacity: 0.55; display: block; margin-top: 2px; }
        .campo-rounds-count-link { cursor: pointer; text-decoration: underline; color: var(--accent); font-weight: 700; }
        .ai-report-header { display: flex; flex-direction: column; gap: 3px; font-size: 0.72rem; opacity: 0.75; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; margin-bottom: 12px; }
        .ai-report-header b { font-weight: 700; opacity: 0.9; }
        .btn-del-row { background: none; border: none; color: var(--danger); font-size: 1.1rem; cursor: pointer; padding: 2px 6px; }

        /* CONTENEDOR DEL GRÁFICO */
        .chart-container { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px; margin-bottom: 15px; height: 220px; position: relative; box-shadow: var(--shadow-sm); }

        /* TOAST NOTIFICACIONES */
        .toast { position: fixed; bottom: -100px; left: 50%; transform: translateX(-50%); background-color: var(--card-bg); color: var(--text); border: 1px solid var(--border); padding: 13px 24px; border-radius: 30px; font-size: 0.95rem; font-weight: 500; box-shadow: var(--shadow-lg); transition: bottom 0.4s, visibility 0.4s, background-color 0.3s, color 0.3s, border-color 0.3s; z-index: 9999; text-align: center; max-width: min(92vw, 420px); max-height: 60vh; overflow-y: auto; visibility: hidden; }
        /* +env(safe-area-inset-bottom): en Android edge-to-edge (obligatorio
           desde Android 15) la barra de gestos/navegación puede pintarse
           encima del contenido si no se reserva ese hueco a propósito. */
        .toast.show { bottom: calc(40px + env(safe-area-inset-bottom)); visibility: visible; }
        .btn-undo { background: var(--accent-soft); border: 1px solid var(--accent); color: var(--accent); padding: 5px 12px; border-radius: 20px; font-weight: 700; font-size: 0.82rem; margin-left: 8px; cursor: pointer; }
        .btn-undo:active { background-color: var(--accent); color: white; }

        /* MODAL DE CONFIRMACIÓN (sustituye al confirm() nativo) */
        /* El padding vertical suma env(safe-area-inset-*) para que, en
           móviles con la barra de navegación superpuesta (edge-to-edge), la
           tarjeta del modal (y sus botones de abajo, p.ej. "Anterior" /
           "Hoyo 2 ▶" en la tarjeta hoyo a hoyo) nunca quede tapada ni fuera
           de la zona pulsable real de la pantalla. */
        .confirm-overlay { position: fixed; inset: 0; background: rgba(10,20,14,0.55); backdrop-filter: blur(1px); display: flex; align-items: center; justify-content: center; z-index: 10000; padding: calc(20px + env(safe-area-inset-top)) 20px calc(20px + env(safe-area-inset-bottom)) 20px; box-sizing: border-box; }
        .confirm-box { background: var(--card-bg); border-radius: var(--radius-lg); padding: 26px 22px; max-width: 320px; width: 100%; text-align: center; box-shadow: var(--shadow-lg); animation: confirmPop 0.15s ease-out; }
        @keyframes confirmPop { from { transform: scale(0.92); opacity: 0; } to { transform: scale(1); opacity: 1; } }
        .confirm-icon { font-size: 2rem; margin-bottom: 8px; }
        .confirm-title { font-size: 1.05rem; font-weight: 700; color: var(--text); margin-bottom: 6px; }
        .confirm-text { font-size: 0.85rem; color: var(--text); opacity: 0.7; margin-bottom: 20px; }
        .confirm-btns { display: flex; gap: 10px; }
        .confirm-btn-cancel, .confirm-btn-delete { flex: 1; padding: 12px 0; border-radius: var(--radius-sm); border: none; font-weight: 700; font-size: 0.9rem; cursor: pointer; }
        .confirm-btn-cancel { background: var(--border); color: var(--text); }
        .confirm-btn-delete { background: var(--danger); color: white; }
        .confirm-btn-cancel:active, .confirm-btn-delete:active { opacity: 0.8; transform: scale(0.98); }

        /* MODAL DE DETALLE DE TIROS (SwingSync) */
        /* max-height combina 80vh (tope habitual) con el alto real disponible
           una vez restado el padding del overlay y las zonas seguras
           (notch arriba, barra de navegación abajo) — así el cuadro nunca
           puede acabar más alto que el hueco visible de verdad, y sus
           botones de abajo siempre quedan dentro de la pantalla pulsable. */
        .shot-detail-box { background: var(--card-bg); border-radius: var(--radius-lg); padding: 0; max-width: 480px; width: 100%; max-height: min(80vh, calc(100vh - 40px - env(safe-area-inset-top) - env(safe-area-inset-bottom))); display: flex; flex-direction: column; box-shadow: var(--shadow-lg); animation: confirmPop 0.15s ease-out; overflow: hidden; }
        .shot-detail-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--border); font-weight: 800; font-size: 0.9rem; color: var(--text); }
        .btn-shot-back, .btn-shot-close { background: var(--border); color: var(--text); border: none; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; font-size: 0.9rem; flex-shrink: 0; }
        .shot-detail-header span { flex: 1; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        /* flex:1 + min-height:0 es necesario para que overflow-y:auto funcione de
           verdad dentro de un padre flex-column: sin min-height:0 el valor por
           defecto (auto) impide que este bloque se encoja por debajo de su
           contenido, así que en tarjetas largas (p.ej. la de hoyo a hoyo) el
           contenido se salía del cuadro en vez de hacer scroll dentro de él. */
        .shot-detail-body { padding: 14px 16px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
        /* Pie fijo (fuera del área con scroll) para modales largos como la
           tarjeta de hoyo a hoyo: así los botones de navegación (Anterior/
           Siguiente) quedan SIEMPRE visibles y pulsables, sin depender de
           que el usuario haga scroll hasta el final del contenido. */
        .shot-detail-footer { padding: 12px 16px; padding-bottom: calc(12px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); flex: 0 0 auto; }
        .shot-detail-footer .hole-row { margin-top: 0 !important; }
        .club-row-tap { cursor: pointer; }
        .club-row-tap:active { opacity: 0.7; }

        /* SELECTOR DE CAMPO CON ESTÉTICA PROPIA — sustituye al <select> nativo
           (en Android WebView se abría como una lista de sistema a pantalla
           completa, en negro puro y sin nada del estilo de la app). */
        .custom-select-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--input-bg); color: var(--text); font-size: 0.88rem; font-family: inherit; cursor: pointer; text-align: left; }
        .custom-select-btn:active { opacity: 0.75; }
        .custom-select-btn-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .custom-select-btn-arrow { flex: 0 0 auto; opacity: 0.55; font-size: 0.75rem; }
        .custom-select-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 4px; border-bottom: 1px solid var(--border); cursor: pointer; font-size: 0.88rem; }
        .custom-select-row:last-child { border-bottom: none; }
        .custom-select-row:active { opacity: 0.7; }
        .custom-select-row.selected { color: var(--accent); font-weight: 700; }

        /* SELECTOR DE FECHA CON ESTÉTICA PROPIA — sustituye al <input type="date">
           nativo, que en Android también se abre como un diálogo de sistema
           fuera de la estética de la app. */
        .date-picker-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 4px; }
        .date-picker-nav-btn { background: var(--input-bg); border: 1px solid var(--border); color: var(--text); border-radius: var(--radius-sm); width: 34px; height: 34px; font-size: 1.05rem; line-height: 1; cursor: pointer; flex: 0 0 auto; }
        .date-picker-nav-btn:active { opacity: 0.7; }
        .date-picker-month-label { font-weight: 700; font-size: 0.92rem; text-transform: capitalize; flex: 1; text-align: center; }
        /* Fila para escribir la fecha a mano, como alternativa a tocar el
           calendario — sobre todo pensada para la fecha de nacimiento, donde
           ir mes a mes 50 años atrás era muy incómodo. */
        .date-picker-manual-row { display: flex; gap: 8px; margin-bottom: 14px; }
        .date-picker-manual-row .note-input { flex: 1; text-align: center; letter-spacing: 0.5px; }
        .date-picker-manual-row .btn-export { flex: 0 0 auto; width: auto; padding: 10px 16px; margin-top: 0; }
        .date-picker-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 0.68rem; opacity: 0.55; margin-bottom: 4px; }
        .date-picker-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
        .date-picker-day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-sm); font-size: 0.82rem; cursor: pointer; background: var(--input-bg); }
        .date-picker-day:active { opacity: 0.7; }
        .date-picker-day.other-month { opacity: 0.28; }
        .date-picker-day.today { border: 1px solid var(--accent); }
        .date-picker-day.selected { background: var(--accent); color: #fff; font-weight: 700; }
        .toast.error { background: linear-gradient(135deg, rgba(220,38,38,0.10), transparent 65%), var(--card-bg); border-color: var(--danger); color: var(--danger); }

        .hidden { display: none !important; }

        /* --- Partido hoyo a hoyo --- */
        .hole-progress-track { height: 4px; background: var(--border); border-radius: 4px; margin-bottom: 16px; overflow: hidden; }
        .hole-progress-fill { height: 100%; background: var(--accent); }
        .hole-counter-card { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px 14px; margin-bottom: 10px; }
        .hole-counter-label { font-size: 0.8rem; font-weight: 700; opacity: 0.75; }
        .hole-row { display: flex; align-items: center; justify-content: space-between; }
        .hole-stepper-btn { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--border); background: var(--card-bg); color: var(--text); font-size: 1.1rem; font-weight: 800; line-height: 1; }
        .hole-stepper-btn:active { opacity: 0.7; transform: scale(0.96); }
        .hole-stepper-value { font-size: 1.3rem; font-weight: 800; min-width: 28px; text-align: center; }
        .hole-hazard-row { display: flex; gap: 8px; flex-wrap: wrap; }
        .hole-chip { padding: 8px 12px; border-radius: 20px; border: 1px solid var(--border); background: var(--card-bg); color: var(--text); font-size: 0.78rem; font-weight: 700; }
        .hole-chip.hole-chip-active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
        .hole-hazard-counters { display: flex; flex-direction: column; gap: 10px; }
        .hole-hazard-counter { display: flex; align-items: center; justify-content: space-between; }
        .hole-hazard-counter-label { font-size: 0.82rem; font-weight: 600; }
        .hole-stepper-btn-sm { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--border); background: var(--card-bg); color: var(--text); font-size: 1rem; font-weight: 800; line-height: 1; }
        .hole-stepper-btn-sm:active { opacity: 0.7; transform: scale(0.96); }
        .hole-stepper-value-sm { font-size: 1.05rem; font-weight: 800; min-width: 20px; text-align: center; }
        .hole-hazard-counter[data-active="true"] .hole-hazard-counter-label { color: var(--accent); }
        /* Este modal se usa para confirmar acciones (salir, descartar...) por encima
           de OTRO modal que se queda abierto detrás (p.ej. la tarjeta hoyo a hoyo o
           el resumen del partido). Todos los .confirm-overlay comparten z-index, y
           en el orden del documento este modal aparece ANTES que esos otros, así que
           sin esto quedaba pintado por debajo: se veía como si la "X"/"Cancelar" no
           hiciera nada, cuando en realidad el diálogo de confirmación se abría oculto
           e inalcanzable. */
        #generic_confirm_overlay { z-index: 10010; }
        #hole_fir_si.hole-toggle-active-good, #hole_fir_no.hole-toggle-active-bad { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
        .hole-stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
        .hole-stat-card { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 10px; text-align: center; }
        .hole-stat-label { font-size: 0.68rem; opacity: 0.65; font-weight: 700; text-transform: uppercase; margin-bottom: 4px; }
        .hole-stat-value { font-size: 1.15rem; font-weight: 800; }
        .hole-stat-help { font-size: 0.65rem; opacity: 0.55; margin-top: 2px; }
        .hole-readonly-value { padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--input-bg); font-weight: 700; }
        .round-start-holes-btn.active { border-color: var(--accent); color: var(--accent); font-weight: 800; }

        /* Transición suave al cambiar entre pantallas principales (switchView) */
        #view_menu, #view_training, #view_stats, #view_distances, #view_ficha, #view_partidos {
            transition: opacity 0.28s ease, transform 0.28s ease;
        }
        #view_menu.view-enter, #view_training.view-enter, #view_stats.view-enter,
        #view_distances.view-enter, #view_ficha.view-enter, #view_partidos.view-enter {
            opacity: 0;
            transform: translateY(10px);
        }

        /* RESUMEN SEMANAL EN LA PANTALLA PRINCIPAL */
        .week-summary-card { background: var(--card-bg); border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius-md); padding: 13px 15px; margin-bottom: 10px; cursor: pointer; box-shadow: var(--shadow-sm); }
        .week-summary-card:active { opacity: 0.8; transform: scale(0.99); }
        .week-summary-sunday { border-left-color: var(--danger); }
        .week-summary-day { font-weight: 800; font-size: 0.95rem; color: var(--accent); display: flex; justify-content: space-between; align-items: baseline; text-transform: uppercase; letter-spacing: 0.3px; }
        .week-summary-sunday .week-summary-day { color: var(--danger); }
        .week-summary-time { font-size: 0.72rem; font-weight: 600; opacity: 0.65; text-transform: none; letter-spacing: normal; }
        .week-summary-line { font-size: 0.8rem; margin-top: 5px; line-height: 1.4; color: var(--text); opacity: 0.9; }
        .week-summary-line b { font-weight: 700; opacity: 1; }

        /* INTRO DE INICIO — un único overlay que se ve nada más cargar la
           WebView, por encima de todo (incluso del auth_gate). Dentro tiene
           DOS CAPAS superpuestas, no dos pantallas distintas:
             1) el <video>, a pantalla completa.
             2) la capa de marca (icono ⛳ + título + línea + lema), encima
                del vídeo, sobre fondo verde oscuro opaco.
           Al terminar el vídeo (o saltarlo) el vídeo simplemente se
           desvanece y la capa de marca se enciende ENCIMA de él, dentro del
           mismo overlay — así nunca hay un hueco de por medio en el que se
           llegue a ver la app de fondo. Solo al final se desvanece el
           overlay entero (las dos capas juntas) y se retira del todo. */
        #intro_overlay { position: fixed; inset: 0; z-index: 99999; background: #000; overflow: hidden; transition: opacity 0.4s ease; }
        #intro_overlay.fading { opacity: 0; pointer-events: none; }

        /* Capa 1: el vídeo */
        #intro_overlay video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.15s ease; }
        #intro_overlay video.playing { opacity: 1; }
        #intro_video_skip { position: absolute; z-index: 3; top: max(16px, env(safe-area-inset-top)); right: 16px; background: rgba(0,0,0,0.45); color: #fff; border: 1px solid rgba(255,255,255,0.5); border-radius: 20px; padding: 7px 16px; font-size: 0.8rem; font-weight: 600; transition: opacity 0.25s ease; }
        #intro_video_skip.fading { opacity: 0; }

        /* Capa 2: la marca, como un rótulo ABAJO A LA IZQUIERDA sobre el
           último fotograma del vídeo (que se queda congelado y visible
           detrás, ver JS) — ya NO es una pantalla que tapa la foto: es un
           texto pequeño superpuesto en la esquina, con solo un degradado
           oscuro muy sutil en la franja de abajo para que se lea bien
           encima de cualquier fotograma. */
        #intro_title_layer { position: absolute; inset: 0; z-index: 2; opacity: 0; pointer-events: none; transition: opacity 0.35s ease; }
        #intro_title_layer.intro-title-hidden { display: none; }
        #intro_title_layer.playing { opacity: 1; }
        #intro_title_layer::before { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 42%; background: linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0) 100%); }
        .intro-title-content { position: absolute; left: max(22px, env(safe-area-inset-left)); right: max(22px, env(safe-area-inset-right)); bottom: max(26px, env(safe-area-inset-bottom)); text-align: left; }
        .intro-title-icon { font-size: 1.15em; margin-right: 6px; display: inline-block; vertical-align: -0.05em; transform: scale(0) rotate(-25deg); opacity: 0; animation: introIconPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s forwards; }
        .intro-title-text { margin: 0; font-size: 1.55rem; font-weight: 800; letter-spacing: 0.3px; line-height: 1.2; text-transform: uppercase; opacity: 0; transform: translateY(12px); animation: introTitleUp 0.5s ease 0.35s forwards; text-shadow: 0 2px 12px rgba(0,0,0,0.55); background: linear-gradient(100deg, #ffffff 40%, #7bffb0 50%, #ffffff 60%); background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
        .intro-title-pro { color: var(--accent); -webkit-text-fill-color: var(--accent); }
        .intro-title-underline { width: 120px; height: 3px; margin: 8px 0 0; background: linear-gradient(90deg, #48bb78, #38a169); border-radius: 3px; transform-origin: center; transform: scaleX(0); animation: introUnderline 0.45s ease 0.8s forwards; }
        .intro-title-tagline { margin: 7px 0 0; font-size: 0.78rem; color: rgba(255,255,255,0.85); font-style: italic; text-shadow: 0 1px 8px rgba(0,0,0,0.6); opacity: 0; animation: introTaglineIn 0.45s ease 0.98s forwards; }
        @keyframes introIconPop { to { transform: scale(1) rotate(0deg); opacity: 1; } }
        @keyframes introTitleUp { 0% { opacity: 0; transform: translateY(12px); background-position: 100% 0; } 60% { opacity: 1; transform: translateY(0); } 100% { opacity: 1; transform: translateY(0); background-position: 0 0; } }
        @keyframes introUnderline { to { transform: scaleX(1); } }
        @keyframes introTaglineIn { to { opacity: 1; } }

        /* ANIMACIONES DE INSIGNIAS Y SUBIDA DE NIVEL */
        .badge-animation-overlay {
            position: fixed;
            inset: 0;
            z-index: 9999;
            background: rgba(0, 0, 0, 0.65);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px;
            animation: backdropFadeIn 0.3s ease;
            backdrop-filter: blur(2px);
        }

        .badge-animation-overlay.closing {
            animation: backdropFadeOut 0.3s ease forwards;
        }

        .badge-animation-container {
            position: relative;
            width: 100%;
            max-width: 320px;
        }

        .confetti-container {
            position: absolute;
            inset: 0;
            pointer-events: none;
            overflow: hidden;
        }

        .confetti {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            bottom: 100vh;
            animation: confettiFall linear forwards;
        }

        @keyframes confettiFall {
            to {
                transform: translateY(-100vh) rotate(360deg);
                opacity: 0;
            }
        }

        .badge-card {
            background: var(--card-bg);
            border-radius: var(--radius-lg);
            padding: 32px 24px 28px;
            box-shadow: var(--shadow-lg);
            text-align: center;
            animation: badgeCardBounceIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
            position: relative;
            z-index: 1;
        }

        .level-up-card {
            padding: 28px 20px 24px;
        }

        @keyframes badgeCardBounceIn {
            0% {
                opacity: 0;
                transform: scale(0.3) translateY(40px);
            }
            50% {
                transform: scale(1.05);
            }
            100% {
                opacity: 1;
                transform: scale(1) translateY(0);
            }
        }

        .badge-icon-wrapper {
            margin-bottom: 18px;
        }

        /* v6.134 — FIX: mismo problema que .badge-name (ver comentario más
           abajo, línea ~740): esta regla se llamaba ".badge-icon", igual
           que el icono pequeño de la cuadrícula de Insignias (línea ~256,
           1.7rem). Al coincidir el nombre, el font-size de esta versión
           grande (3.5rem, con animación de pulso y brillo, pensada solo
           para el icono del modal "¡Insignia desbloqueada!") ganaba para
           TODOS los .badge-icon, incluida la cuadrícula pequeña — icono
           gigante y pulsando donde debía verse un emoji pequeño y quieto.
           Se renombra a .badge-anim-icon (único, solo para el modal). */
        .badge-anim-icon {
            font-size: 3.5rem;
            display: inline-block;
            animation: badgeIconPulse 1.5s ease-in-out infinite;
            filter: drop-shadow(0 0 12px rgba(22, 163, 74, 0.4));
            text-shadow: 0 0 20px rgba(22, 163, 74, 0.3);
        }

        .level-up-icon {
            animation: levelUpIconBounce 1s ease-in-out infinite;
        }

        @keyframes badgeIconPulse {
            0%, 100% {
                transform: scale(1);
                filter: drop-shadow(0 0 12px rgba(22, 163, 74, 0.4));
            }
            50% {
                transform: scale(1.15);
                filter: drop-shadow(0 0 24px rgba(22, 163, 74, 0.6));
            }
        }

        @keyframes levelUpIconBounce {
            0%, 100% {
                transform: translateY(0) scale(1);
            }
            50% {
                transform: translateY(-8px) scale(1.1);
            }
        }

        .badge-content {
            animation: badgeContentFadeIn 0.5s ease 0.2s backwards;
        }

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

        /* v6.130 — FIX: esta regla se llamaba antes ".badge-name", igual que
           la de la cuadrícula de Insignias (línea ~258, 0.72rem, para las
           tarjetas pequeñas CONSTANCIA/COMPETIDOR/...). Al coincidir el
           nombre, esta versión grande (pensada solo para el título del
           modal "¡Insignia desbloqueada!") ganaba por ir después en el
           fichero y se aplicaba también a las tarjetas pequeñas, haciendo
           que el texto se saliera de la tarjeta y se montara con la de al
           lado. Se renombra a .badge-anim-name (único, solo para el modal)
           para que cada uno tenga su propio tamaño. */
        .badge-anim-name {
            font-size: 1.3rem;
            font-weight: 800;
            color: var(--text);
            margin: 0 0 14px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .badge-medal-row {
            display: flex;
            justify-content: center;
            gap: 8px;
            align-items: center;
        }

        .badge-medal {
            font-size: 2.2rem;
            display: inline-block;
            animation: badgeMedalSpinIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.3s backwards;
        }

        @keyframes badgeMedalSpinIn {
            0% {
                opacity: 0;
                transform: scale(0) rotateY(90deg);
            }
            100% {
                opacity: 1;
                transform: scale(1) rotateY(0deg);
            }
        }

        .level-progression {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            margin: 16px 0;
            font-size: 0.95rem;
            font-weight: 700;
            flex-wrap: wrap;
        }

        .level-name {
            padding: 6px 12px;
            border-radius: var(--radius-sm);
            background: var(--border);
            color: var(--text);
            transition: all 0.4s ease;
        }

        .level-name.active {
            background: var(--accent);
            color: white;
            transform: scale(1.1);
            box-shadow: 0 0 16px rgba(22, 163, 74, 0.4);
        }

        .level-arrow {
            opacity: 0.5;
            font-size: 1.2rem;
        }

        .current-level-highlight {
            font-size: 0.9rem;
            color: var(--accent);
            font-weight: 700;
            margin-top: 14px;
            padding: 10px;
            border-radius: var(--radius-sm);
            background: var(--accent-soft);
            letter-spacing: 0.3px;
        }

        .current-level-highlight strong {
            font-size: 1.05rem;
            color: var(--accent);
        }

        @keyframes backdropFadeIn {
            from {
                opacity: 0;
            }
            to {
                opacity: 1;
            }
        }

        @keyframes backdropFadeOut {
            from {
                opacity: 1;
            }
            to {
                opacity: 0;
            }
        }

        /* Responsive */
        @media (max-width: 480px) {
            .badge-card {
                padding: 28px 20px 24px;
            }

            .badge-anim-icon {
                font-size: 3rem;
            }

            .badge-anim-name {
                font-size: 1.15rem;
            }

            .level-progression {
                font-size: 0.85rem;
            }

            .badge-medal {
                font-size: 1.8rem;
            }
        }

        /* BOTÓN FLOTANTE "Consulta al profe" (accesible desde cualquier pantalla) */
        .profe-fab {
            position: fixed;
            right: 18px;
            bottom: calc(90px + env(safe-area-inset-bottom));
            z-index: 500;
            width: 56px;
            height: 56px;
            border-radius: 50%;
            /* v6.187.0 — el botón es un círculo, pero sin clip-path su caja
               de impacto (hit-box) seguía siendo el cuadrado completo de
               56x56, así que las esquinas transparentes (donde no se ve
               nada del botón) interceptaban igualmente los toques
               destinados a lo que hubiera debajo — p.ej. el "🗑️ Borrar" de
               una tarjeta del Historial cuyo botón cayera justo bajo una
               esquina del FAB, sin que se viera el FAB encima. Con
               clip-path, solo el círculo visible es clicable de verdad. */
            clip-path: circle(50% at 50% 50%);
            border: none;
            background: linear-gradient(135deg, var(--purple), var(--accent));
            color: #fff;
            font-size: 1.55rem;
            box-shadow: var(--shadow-lg);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .profe-fab:active { transform: scale(0.93); }
        .profe-fab-icon { display: block; }

        .btn-mic {
            flex: 0 0 auto;
            width: 46px;
            height: 46px;
            border-radius: 50%;
            border: 1px solid var(--border);
            background: var(--card-bg);
            color: var(--text);
            font-size: 1.15rem;
            cursor: pointer;
            box-shadow: var(--shadow-sm);
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .btn-mic.mic-recording { background: var(--danger); color: #fff; border-color: var(--danger); animation: pulseTimer 1s ease-in-out infinite; }

        /* Corrección de contraste en modo oscuro: estas insignias usaban un
           color de texto oscuro fijo sobre un fondo translúcido que tampoco
           se adapta al tema — en modo oscuro el fondo se vuelve casi negro y
           el texto (también oscuro) deja de leerse. Ahora usan los mismos
           colores --success/--danger de siempre, que sí cambian con el tema. */
        .badge-yes { background: rgba(34,197,94,0.16); color: var(--success); padding: 4px 10px; border-radius: 20px; font-weight: bold; font-size: 0.72rem; }
        .badge-no { background: rgba(220,38,38,0.14); color: var(--danger); padding: 4px 10px; border-radius: 20px; font-weight: bold; font-size: 0.72rem; }
        .badge-consist { display: inline-block; padding: 4px 10px; border-radius: 20px; font-weight: bold; font-size: 0.7rem; white-space: nowrap; }
        .badge-consist-excelente { background: rgba(34,197,94,0.16); color: var(--success); }
        .badge-consist-buena { background: rgba(250,204,21,0.20); color: var(--text); }
        .badge-consist-mejorable { background: rgba(251,146,60,0.20); color: var(--text); }
        .badge-consist-trabajar { background: rgba(220,38,38,0.14); color: var(--danger); }
        .badge-consist-sindatos { background: var(--border); color: var(--text); opacity: 0.6; }

        /* ===================================================================
           SWING VIDEO — modal "Analizar swing" (v6.166.0)
           Antes usaba las clases .confirm-modal / .close-btn, que no existían
           en esta hoja de estilos: por eso se veía sin ningún estilo (caja
           blanca por defecto del navegador, sin bordes redondeados, sin
           sombra, botones planos). Ahora reutiliza el mismo patrón visual
           que el resto de modales de la app (.shot-detail-box / header) y
           añade estilos propios coherentes con el tema verde de la app.
           =================================================================== */
        .swing-video-box { max-width: 420px; }
        .swing-video-intro { background: var(--accent-soft); border-radius: var(--radius-md); padding: 13px 14px; margin-bottom: 16px; font-size: 0.85rem; line-height: 1.5; color: var(--text); }
        .swing-video-intro-sub { opacity: 0.75; margin-top: 6px; font-size: 0.8rem; }

        .swing-video-preview-wrap { position: relative; margin-bottom: 14px; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-md); }
        .swing-video-preview { width: 100%; display: block; background: #000; max-height: 280px; object-fit: cover; }
        .swing-video-rec-badge { position: absolute; top: 10px; left: 10px; display: flex; align-items: center; gap: 6px; background: rgba(0,0,0,0.6); backdrop-filter: blur(2px); color: #fff; padding: 5px 11px; border-radius: 20px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.4px; }
        .swing-video-rec-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); animation: pulseTimer 1s ease-in-out infinite; }

        .swing-video-actions { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
        .swing-video-actions .btn-save { margin-top: 0; display: flex; align-items: center; justify-content: center; gap: 8px; }
        .swing-video-btn-stop { background-color: var(--danger) !important; }
        .swing-video-btn-icon { font-size: 1rem; }

        .swing-video-divider { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; opacity: 0.55; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }
        .swing-video-divider::before, .swing-video-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

        .swing-video-upload-zone { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 16px 12px; margin-bottom: 6px; border: 1.5px dashed var(--border); border-radius: var(--radius-md); background: var(--card-bg); color: var(--text); cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; }
        .swing-video-upload-zone:active { border-color: var(--accent); background: var(--accent-soft); }
        .swing-video-upload-icon { font-size: 1.4rem; margin-bottom: 2px; }
        .swing-video-upload-zone > span:nth-child(2) { font-weight: 700; font-size: 0.9rem; }
        .swing-video-upload-sub { font-size: 0.72rem; opacity: 0.6; }
        .swing-video-upload-status { font-size: 0.78rem; color: var(--accent); font-weight: 600; margin: 8px 0 14px; text-align: center; }

        .swing-video-tips { font-size: 0.75rem; opacity: 0.6; margin-top: 14px; text-align: center; line-height: 1.5; }

        .swing-video-answer-title { margin-bottom: 12px; font-size: 1.1rem; text-align: center; color: var(--accent); }

        /* Galería de swings guardados en el propio dispositivo (IndexedDB) */
        .swing-video-gallery-section { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
        .swing-video-gallery-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
        .swing-video-delete-all-btn { background: none; border: none; color: var(--danger); font-size: 0.74rem; font-weight: 700; cursor: pointer; padding: 4px 6px; opacity: 0.85; }
        .swing-video-delete-all-btn:active { opacity: 0.6; }
        .swing-video-gallery-empty { font-size: 0.8rem; opacity: 0.55; text-align: center; padding: 10px 0; }
        .swing-video-gallery-list { display: flex; flex-direction: column; gap: 8px; }
        .swing-video-item { display: flex; align-items: center; gap: 10px; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 9px 10px; box-shadow: var(--shadow-sm); cursor: pointer; }
        .swing-video-item:active { background: var(--accent-soft); }
        .swing-video-item-thumb { flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
        .swing-video-item-info { flex: 1; min-width: 0; }
        .swing-video-item-date { font-size: 0.83rem; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .swing-video-item-meta { font-size: 0.72rem; opacity: 0.6; margin-top: 1px; }
        .swing-video-item-analyzed { color: var(--accent); font-weight: 700; }
        .swing-video-item-delete { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; color: var(--danger); font-size: 0.95rem; cursor: pointer; }
        .swing-video-item-delete:active { background: rgba(220,38,38,0.14); }

        .swing-video-player-box { max-width: 420px; }
        #swing_video_player { width: 100%; border-radius: var(--radius-md); background: #000; }

        /* ============================================================
           v6.167.0 — Zoom de gráficos (lupa + modal con pinch-to-zoom)
           ============================================================ */
        .chart-zoom-btn {
            position: absolute; top: 6px; right: 6px; z-index: 5;
            width: 30px; height: 30px; border-radius: 50%;
            background: rgba(0,0,0,0.45); color: #fff; border: 1px solid rgba(255,255,255,0.4);
            display: flex; align-items: center; justify-content: center;
            font-size: 14px; line-height: 1; cursor: pointer;
            box-shadow: var(--shadow-sm);
            transition: background 0.15s ease, transform 0.1s ease;
        }
        .chart-zoom-btn:active { transform: scale(0.9); background: rgba(0,0,0,0.65); }

        body.chart-zoom-open { overflow: hidden; }

        .chart-zoom-modal {
            position: fixed; inset: 0; z-index: 9999;
            display: flex; align-items: center; justify-content: center;
            touch-action: none;
        }
        .chart-zoom-modal.hidden { display: none; }
        .chart-zoom-backdrop {
            position: absolute; inset: 0; background: rgba(10,16,13,0.94); z-index: 0;
        }
        .chart-zoom-close {
            position: absolute; top: max(14px, env(safe-area-inset-top)); right: 16px; z-index: 2;
            width: 38px; height: 38px; border-radius: 50%;
            background: rgba(0,0,0,0.45); color: #fff; border: 1px solid rgba(255,255,255,0.5);
            font-size: 17px; display: flex; align-items: center; justify-content: center;
            cursor: pointer;
        }
        .chart-zoom-close:active { background: rgba(0,0,0,0.65); }
        .chart-zoom-hint {
            position: absolute; bottom: max(18px, env(safe-area-inset-bottom)); left: 12px; right: 12px;
            text-align: center; color: rgba(255,255,255,0.55); font-size: 0.72rem; z-index: 2;
            pointer-events: none;
        }
        .chart-zoom-viewport {
            position: relative; width: 100%; height: 100%;
            display: flex; align-items: center; justify-content: center;
            overflow: hidden; z-index: 1;
        }
        .chart-zoom-viewport img {
            max-width: 92%; max-height: 82%; object-fit: contain;
            background: var(--card-bg); border-radius: var(--radius-md); padding: 12px;
            box-shadow: var(--shadow-lg);
            touch-action: none; will-change: transform; cursor: grab;
        }
