/* Offline Fonts optimized */
        :root {
            --bg: #f0fdf4; --card: #ffffff; --text: #1e293b; --text-secondary: #64748b;
            --primary: #059669; --primary-light: #d1fae5; --primary-dark: #047857;
            --danger: #dc2626; --danger-light: #fee2e2; --warning: #f59e0b;
            --border: #e2e8f0; --nav-bg: #ffffff; --shadow: 0 1px 3px rgba(0,0,0,0.08);
            --radius: 16px; --radius-sm: 10px;
            --surface: var(--card);
            /* Performance tuning (defaults = Balanced + Medium animations) */
            --page-anim: 350ms;
            /* Outgoing-page exit leg. Deliberately much shorter than the entrance:
               the leaving page only has to clear the way, not be admired.
               PAGE_EXIT_MS in js/app.js navigate() must match this. */
            --page-exit: 150ms;
            --tap-scale: 0.98;
            --shadow-soft: var(--shadow);

            /* Custom appearance overrides variables */
            --app-font-scale: 100%;
            --app-font-weight: 400;
            --app-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            --primary-rgb: 5, 150, 105;

            /* ── Type weight ladder ───────────────────────────────────────
               The user's Appearance > Font Weight setting (--app-font-weight,
               one of 300/400/500/600) shifts this whole ladder, so the control
               keeps working exactly as before. Each step is clamped so the
               hierarchy can never collapse into a single weight, and never
               exceeds the heaviest weight Inter actually ships (900).
               At the default 400 this yields the standard 400-900 scale.      */
            --w-normal:    clamp(300, var(--app-font-weight, 400),             600);
            --w-medium:    clamp(400, calc(var(--app-font-weight, 400) + 100), 700);
            --w-semibold:  clamp(500, calc(var(--app-font-weight, 400) + 200), 700);
            --w-bold:      clamp(600, calc(var(--app-font-weight, 400) + 300), 800);
            --w-extrabold: clamp(700, calc(var(--app-font-weight, 400) + 400), 900);
            --w-black:     clamp(800, calc(var(--app-font-weight, 400) + 500), 900);

            /* ── Surface scale ────────────────────────────────────────────
               One radius per role, so sibling cards stop mixing 12/16/24px.  */
            --r-card: 18px;
            --r-control: 12px;
            --r-chip: 999px;
            /* Elevation ramp: flat -> resting card -> raised card -> overlay */
            --elev-1: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.05);
            --elev-2: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 20px -8px rgba(15, 23, 42, 0.10);
            --hairline: rgba(15, 23, 42, 0.07);
            /* Density defaults = "Comfortable": 1rem card padding and the same
               0.875rem vertical rhythm the markup already used (space-y-3.5). */
            --card-pad: 1rem;
            --stack-gap: 0.875rem;
        }
        .dark {
            /* Dark-mode counterparts of the surface tokens declared in :root */
            --elev-1: 0 1px 2px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.24);
            --elev-2: 0 1px 2px rgba(0, 0, 0, 0.30), 0 10px 24px -8px rgba(0, 0, 0, 0.55);
            --hairline: rgba(255, 255, 255, 0.08);
        }
        .dark {
            --bg: #0f172a; --card: #1e293b; --text: #f1f5f9; --text-secondary: #94a3b8;
            --primary: #10b981; --primary-light: #064e3b; --primary-dark: #34d399;
            --danger: #ef4444; --danger-light: #450a0a; --warning: #fbbf24;
            --border: #334155; --nav-bg: #1e293b; --shadow: 0 1px 3px rgba(0,0,0,0.3);
            --primary-rgb: 16, 185, 129;
            --surface: var(--card);
        }
        html {
            font-size: var(--app-font-scale) !important;
        }
        body {
            font-family: var(--app-font-family), 'Inter', sans-serif !important; 
            background-color: var(--bg); color: var(--text);
            transition: all 0.35s; min-height: 100vh;
            padding-bottom: 0;
            padding-top: env(safe-area-inset-top); -webkit-tap-highlight-color: transparent;
        }
        /*
           Font family is still forced on these tags (some UA stylesheets refuse
           to inherit it). Font weight, however, is now inherited from <body>
           instead of being forced here: the old `font-weight: ... !important`
           on this tag list out-ranked every utility class and every component
           rule, which flattened the whole UI to two weights.
        */
        body, p, span, li, td, th, input, select, textarea, button {
            font-family: var(--app-font-family), inherit !important;
        }
        body {
            font-weight: var(--app-font-weight, 400);
        }
        /* Form controls don't inherit font-weight from their parent by default. */
        input, select, textarea, button {
            font-weight: inherit;
        }
        /*
           Real weight ladder. Previously .font-bold / .font-extrabold /
           .font-black all resolved to the same value, so nothing could stand
           out. Each utility now maps to its own step of the ladder defined in
           :root, which still tracks the user's Font Weight setting.
        */
        .font-normal    { font-weight: var(--w-normal)    !important; }
        .font-medium    { font-weight: var(--w-medium)    !important; }
        .font-semibold  { font-weight: var(--w-semibold)  !important; }
        .font-bold      { font-weight: var(--w-bold)      !important; }
        .font-extrabold { font-weight: var(--w-extrabold) !important; }
        .font-black     { font-weight: var(--w-black)     !important; }
        h1, h2, h3, h4, h5, h6 {
            font-weight: var(--w-bold);
            letter-spacing: -0.011em;
        }
        
       /* Accent override rules to map Tailwind colors dynamically */
        .custom-accent-active .bg-emerald-600, 
        .custom-accent-active .bg-emerald-500, 
        .custom-accent-active .bg-teal-600, 
        .custom-accent-active .bg-indigo-600, 
        .custom-accent-active .bg-indigo-650, 
        .custom-accent-active .bg-indigo-700 {
            background-color: var(--primary) !important;
        }
        .custom-accent-active .hover\:bg-emerald-500:hover, 
        .custom-accent-active .hover\:bg-emerald-600:hover, 
        .custom-accent-active .hover\:bg-indigo-600:hover, 
        .custom-accent-active .hover\:bg-indigo-700:hover {
            background-color: var(--primary-dark) !important;
        }
        .custom-accent-active .text-emerald-600, 
        .custom-accent-active .text-emerald-500, 
        .custom-accent-active .text-emerald-700, 
        .custom-accent-active .text-indigo-600, 
        .custom-accent-active .text-indigo-700 {
            color: var(--primary) !important;
        }
        .custom-accent-active .border-emerald-500, 
        .custom-accent-active .border-emerald-600, 
        .custom-accent-active .border-indigo-500, 
        .custom-accent-active .border-indigo-600 {
            border-color: var(--primary) !important;
        }
        .custom-accent-active .bg-emerald-50, 
        .custom-accent-active .bg-indigo-50 {
            background-color: var(--primary-light) !important;
        }
        /* `dark` lives on <html> and `custom-accent-active` on <body>, so the
           dark class is an ANCESTOR here, never a descendant. Written the old
           way (.custom-accent-active .dark ...) this rule could never match,
           which left the .bg-emerald-50 mapping above painting these panels
           near-white (#d1fae5) in dark mode. */
        .dark .custom-accent-active .bg-emerald-950\/20,
        .dark .custom-accent-active .bg-indigo-950\/20 {
            background-color: rgba(var(--primary-rgb), 0.15) !important;
        }
        .custom-accent-active .peer-checked\:bg-emerald-500:checked ~ div {
            background-color: var(--primary) !important;
        }
        
        /* Slate body text colors overrides */
        .custom-text-active .text-slate-900, 
        .custom-text-active .text-slate-800, 
        .custom-text-active .text-slate-705,
        .custom-text-active .text-slate-700, 
        .custom-text-active .text-slate-750, 
        .custom-text-active .text-slate-600 {
            color: var(--text) !important;
        }
        .custom-text-active .text-slate-500,
        .custom-text-active .text-slate-400 {
            color: var(--text-secondary) !important;
        }
        /* Mobile/touch responsiveness & input latency */
        button, a, input, select, textarea { touch-action: manipulation; }
        .pressable { transform: translateZ(0); }
        .pressable:active { transform: scale(var(--tap-scale)); }

        /* Page transitions (tunable via performance settings) */
        .page { display: none; animation: fadeIn var(--page-anim) ease; }
        .page.active { display: block; }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

        /* Reduced motion support (system + in-app setting) */
        @media (prefers-reduced-motion: reduce) {
            :root { --page-anim: 0ms; }
            *, *::before, *::after { animation: none !important; transition-duration: 0ms !important; scroll-behavior: auto !important; }
            .option-entrance { opacity: 1 !important; transform: none !important; }
        }
        html[data-reduce-motion="true"] {
            --page-anim: 0ms;
        }
        html[data-reduce-motion="true"] *, html[data-reduce-motion="true"] *::before, html[data-reduce-motion="true"] *::after {
            animation: none !important;
            transition-duration: 0ms !important;
            scroll-behavior: auto !important;
        }
        html[data-reduce-motion="true"] .option-entrance {
            opacity: 1 !important;
            transform: none !important;
        }
        /* एनिमेसन सुधार नियमहरू */
@keyframes floatExplode {
    0% { opacity: 0; transform: translate(0, 0) scale(0.5); }
    30% { opacity: 1; transform: translate(var(--tx), var(--ty)) scale(1.2); }
    100% { opacity: 0; transform: translate(var(--tx), var(--ty)) scale(0.8); }
}
@keyframes pulse-alert {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.65; transform: scale(1.01); }
}
.animate-pulse-alert {
    animation: pulse-alert 1.5s infinite ease-in-out !important;
}
        /* सच्याइएको एनिमेसन कोड (Sparkle & Pulse Warning Fix) */
@keyframes floatExplode {
    0% { opacity: 0; transform: translate(0, 0) scale(0.5); }
    30% { opacity: 1; transform: translate(var(--tx), var(--ty)) scale(1.2); }
    100% { opacity: 0; transform: translate(var(--tx), var(--ty)) scale(0.8); }
}
@keyframes pulse-alert {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.65; transform: scale(1.01); }
}
.animate-pulse-alert {
    animation: pulse-alert 1.5s infinite ease-in-out !important;
}
        html[data-perf-mode="battery"] {
            --shadow-soft: 0 0 0 rgba(0,0,0,0);
            --tap-scale: 1;
        }

        /* Mobile Spacing & Layout Spacing Optimizations (under 768px) */
        @media (max-width: 767px) {
            /* 1. Ensure HTML/body prevents horizontal overflow */
            html, body {
                overflow-x: hidden !important;
                max-width: 100vw !important;
            }
            
            /* 2. Main content container bottom padding to avoid bottom navigation overlap */
            main {
                padding-bottom: 0 !important;
            }
            
            /* 3. Question Card sizing and autosizing height */
            #mcq-card-container {
                height: auto !important;
                min-height: 0 !important;
                padding: 1.25rem !important;
            }
            
            /* 4. MCQ page spacing adjustments */
            #page-mcq {
                padding-left: 0 !important;
                padding-right: 0 !important;
                padding-top: 0.5rem !important;
                padding-bottom: 0.5rem !important;
                gap: 0.5rem !important;
            }
            
            /* 5. Answer options compact spacing & padding */
            #q-options {
                margin-top: 0.75rem !important;
                margin-bottom: 0.75rem !important;
                gap: 0.5rem !important;
            }
            .option-btn {
                padding: 10px 14px !important;
                font-size: 13px !important;
                border-radius: 12px !important;
            }
            
            /* 6. Confidence selector tight spacing & smaller buttons on mobile */
            #confidence-selector-container {
                margin-top: 0.5rem !important;
                padding-top: 0.5rem !important;
            }
            #confidence-selector-container span {
                font-size: 8px !important;
            }
            #confidence-selector-container button {
                padding-top: 0.375rem !important;
                padding-bottom: 0.375rem !important;
                border-radius: 10px !important;
                font-size: 9px !important;
            }
            
            /* 7. Action buttons responsive padding */
            #submit-btn, #next-btn, #finish-btn {
                padding-top: 0.75rem !important;
                padding-bottom: 0.75rem !important;
                border-radius: 12px !important;
                font-size: 13px !important;
            }
        }
        .option-btn {
            transition: 0.2s; cursor: pointer; background: var(--card); border: 2px solid var(--border);
            color: var(--text); border-radius: var(--radius-sm); padding: 14px 16px; font-weight: 500; width: 100%; text-align: left;
        }
        .option-btn:hover { border-color: var(--primary); background: var(--primary-light); }
        .option-btn.selected { border-color: var(--primary); background: var(--primary-light); box-shadow: 0 0 0 3px rgba(5,150,105,0.2); }
        .option-btn.correct { border-color: #059669 !important; background: #d1fae5 !important; color: #065f46 !important; font-weight: 700; }
        .dark .option-btn.correct { background: #064e3b !important; color: #6ee7b7 !important; border-color: #10b981 !important; }
        .option-btn.wrong { border-color: #dc2626 !important; background: #fee2e2 !important; color: #991b1b !important; }
        .dark .option-btn.wrong { background: #450a0a !important; color: #fca5a5 !important; border-color: #ef4444 !important; }
        .option-btn.disabled { pointer-events: none; opacity: 0.8; }
        .streak-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
        .streak-dot.active { background: #10b981; box-shadow: 0 0 8px rgba(16, 185, 129, 0.6); }
        .streak-dot.inactive { background: #cbd5e1; }
        .dark .streak-dot.inactive { background: #475569; }
        .creator-tab {
            cursor: pointer; padding: 10px 16px; border-radius: 20px; font-weight: 600; font-size: 13px;
            transition: 0.2s; border: 1px solid var(--border); background: var(--card); color: var(--text-secondary); white-space: nowrap;
        }
        .creator-tab.active { background: var(--primary); color: #fff; border-color: var(--primary); }
        .badge-status { font-size: 10px; padding: 3px 8px; border-radius: 12px; font-weight: 600; display: inline-block; }
        .badge-draft { background: #fef3c7; color: #92400e; }
        .badge-published { background: #d1fae5; color: #065f46; }
        .badge-revision { background: #fee2e2; color: #991b1b; }
        .dark .badge-draft { background: #78350f; color: #fde68a; }
        .dark .badge-published { background: #064e3b; color: #6ee7b7; }
        .dark .badge-revision { background: #450a0a; color: #fca5a5; }
        
        /* Quill dark mode style overrides */
        .dark .ql-toolbar { background: #1e293b; border-color: #334155 !important; }
        .dark .ql-toolbar .ql-stroke { stroke: #f1f5f9; }
        .dark .ql-toolbar .ql-fill { fill: #f1f5f9; }
        .dark .ql-toolbar .ql-picker { color: #f1f5f9; }
        .dark .ql-container { border-color: #334155 !important; background: #1e293b; }
        .dark .ql-editor { color: #f1f5f9; }

        /* Splash Screen Premium Ultra-HD Glassmorphic Agriculture Styles */
        #splash-screen {
            position: fixed; inset: 0; z-index: 99999;
            background: radial-gradient(circle at 50% 40%, #064e3b 0%, #022c22 65%, #011712 100%);
            display: flex; align-items: center; justify-content: center;
            transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.6s;
            overflow: hidden;
        }
        #splash-screen.hidden { opacity: 0; visibility: hidden; pointer-events: none; }
        
        /* Drifting Ambient Holographic Gradients */
        #splash-screen::before {
            content: ''; position: absolute; inset: -60%;
            background: radial-gradient(circle at 35% 35%, rgba(52, 211, 153, 0.18) 0%, transparent 50%),
                        radial-gradient(circle at 65% 65%, rgba(163, 230, 53, 0.14) 0%, transparent 50%),
                        radial-gradient(circle at 50% 80%, rgba(5, 150, 105, 0.15) 0%, transparent 60%);
            animation: bgDrift 14s ease-in-out infinite alternate;
            pointer-events: none;
            filter: blur(30px);
        }
        @keyframes bgDrift {
            0% { transform: rotate(0deg) scale(1); }
            50% { transform: rotate(10deg) scale(1.08); }
            100% { transform: rotate(-10deg) scale(1.15); }
        }

        /* Organic Mesh Grain Grid */
        .splash-bg-grain {
            position: absolute; inset: 0; opacity: 0.05;
            background-image: radial-gradient(rgba(255,255,255,0.2) 1px, transparent 0),
                              radial-gradient(rgba(255,255,255,0.2) 1px, transparent 0);
            background-size: 10px 10px;
            background-position: 0 0, 5px 5px;
            pointer-events: none;
        }

        /* Glassmorphic Central Card Container */
        .splash-glass-card {
            position: relative; z-index: 10;
            background: rgba(6, 78, 59, 0.4);
            /* removed heavy blur */ -webkit-/* removed heavy blur */
            border: 1px solid rgba(52, 211, 153, 0.28);
            border-radius: 2rem;
            padding: 2.5rem 2rem;
            box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.6),
                        inset 0 1px 1px rgba(255, 255, 255, 0.25),
                        0 0 40px rgba(16, 185, 129, 0.15);
            display: flex; flex-direction: column; align-items: center; justify-content: center;
            width: 320px;
        }

        /* Holographic Double Ring Logo Wrapper */
        .logo-wrapper {
            position: relative; width: 120px; height: 120px;
            display: flex; align-items: center; justify-content: center;
            margin-bottom: 1.5rem;
        }
        .logo-ring-outer {
            position: absolute; inset: 0; border-radius: 50%;
            border: 2px dashed rgba(52, 211, 153, 0.45);
            box-shadow: 0 0 25px rgba(52, 211, 153, 0.3);
            animation: spinRing 12s linear infinite;
        }
        .logo-ring-inner {
            position: absolute; inset: 10px; border-radius: 50%;
            border: 3px solid transparent;
            border-top-color: #34d399; border-right-color: #a3e635; border-bottom-color: #10b981;
            box-shadow: 0 0 15px rgba(52, 211, 153, 0.5);
            animation: spinRingReverse 4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
        }
        .logo-ring-glow {
            position: absolute; inset: 20px; border-radius: 50%;
            background: radial-gradient(circle, rgba(52, 211, 153, 0.35) 0%, transparent 75%);
            animation: ringGlowPulse 2.5s ease-in-out infinite alternate;
        }
        .logo-emoji {
            font-size: 3.5rem; z-index: 10;
            filter: drop-shadow(0 0 18px rgba(52, 211, 153, 0.8));
            animation: sproutBounce 2.5s ease-in-out infinite alternate;
            user-select: none;
        }
        
        @keyframes spinRing {
            to { transform: rotate(360deg); }
        }
        @keyframes spinRingReverse {
            to { transform: rotate(-360deg); }
        }
        @keyframes ringGlowPulse {
            0% { transform: scale(0.85); opacity: 0.5; }
            100% { transform: scale(1.15); opacity: 0.95; }
        }
        @keyframes sproutBounce {
            0% { transform: translateY(0) scale(0.96) rotate(-3deg); filter: drop-shadow(0 0 12px rgba(52, 211, 153, 0.5)); }
            100% { transform: translateY(-8px) scale(1.08) rotate(3deg); filter: drop-shadow(0 0 30px rgba(163, 230, 53, 0.9)); }
        }

        /* Animated Progress Bar & Shimmer */
        #splash-progress {
            background: linear-gradient(90deg, #34d399 0%, #10b981 33%, #a3e635 66%, #34d399 100%);
            background-size: 200% 100%;
            animation: shimmerProgress 2s linear infinite;
            box-shadow: 0 0 12px #34d399;
        }
        @keyframes shimmerProgress {
            0% { background-position: 200% 0; }
            100% { background-position: -200% 0; }
        }

        /* Floating Light Particles */
        .splash-particle {
            position: absolute; background: radial-gradient(circle, rgba(163, 230, 53, 0.7) 0%, rgba(52, 211, 153, 0.3) 70%);
            border-radius: 50%; pointer-events: none;
            filter: blur(1px);
            animation: floatUp 5s linear infinite;
        }
        @keyframes floatUp {
            0% { transform: translateY(110vh) translateX(0) scale(0.8); opacity: 0; }
            15% { opacity: 0.9; }
            85% { opacity: 0.9; }
            100% { transform: translateY(-10vh) translateX(40px) scale(1.3); opacity: 0; }
        }

        /* Prefers Reduced Motion Accessibility Override */
        @media (prefers-reduced-motion: reduce) {
            #splash-screen::before, .logo-ring-outer, .logo-ring-inner, .logo-emoji, .splash-particle, #splash-progress {
                animation: none !important;
                transform: none !important;
            }
            .logo-ring-outer { border: 2px solid rgba(52, 211, 153, 0.4); }
            .logo-ring-inner { border: 3px solid #34d399; }
        }

        /* Rich Animated Study Center styles */
        .home-entrance {
            animation: homeEntranceAnim 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
        }
        @keyframes homeEntranceAnim {
            from { opacity: 0; transform: translateY(15px); }
            to { opacity: 1; transform: translateY(0); }
        }
        .slide-up-card {
            animation: cardSlideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
        }
        @keyframes cardSlideUp {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }
        /* Suppress entrance animations during sync-triggered renders to prevent
           the visible opacity:0 flash when innerHTML rebuilds all widgets */
        .krishi-sync-update .slide-up-card {
            animation: none !important;
        }

        /* ============ STUDENT PROFILE ============ */
        /* Avatar entry button: press feedback only — no constant float (exam-focus UI).
           inline-flex keeps the round avatar optically centred inside the app-wide
           48px mobile touch target instead of sitting hard against its top edge. */
        .profile-avatar-btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            transition: transform 0.16s cubic-bezier(0.16, 1, 0.3, 1);
        }
        .profile-avatar-btn:active {
            transform: scale(0.94);
        }
        /* Subtle one-shot entrance for the profile header avatar */
        .profile-avatar-enter {
            animation: profileAvatarIn 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
        }
        @keyframes profileAvatarIn {
            from { opacity: 0; transform: scale(0.86); }
            to   { opacity: 1; transform: scale(1); }
        }
        /* Staggered card entrance, reusing the app's cardSlideUp curve */
        .profile-card-enter {
            animation: cardSlideUp 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
        }
        .profile-card-enter:nth-child(2) { animation-delay: 0.05s; }
        .profile-card-enter:nth-child(3) { animation-delay: 0.10s; }
        .profile-card-enter:nth-child(4) { animation-delay: 0.15s; }
        /* Same anti-flicker guard the home widgets use: never replay entrances
           when a cloud-sync render rebuilds the DOM */
        .krishi-sync-update .profile-card-enter,
        .krishi-sync-update .profile-avatar-enter {
            animation: none !important;
        }
        /* Sync activity indicator — restrained, only while actually syncing */
        .profile-sync-spin {
            animation: profileSyncSpin 0.9s linear infinite;
            display: inline-block;
        }
        @keyframes profileSyncSpin {
            to { transform: rotate(360deg); }
        }
        /* Save confirmation: brief, non-blocking */
        .profile-saved-flash {
            animation: profileSavedFlash 0.9s ease-out both;
        }
        @keyframes profileSavedFlash {
            0%   { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.45); }
            35%  { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.28); }
            100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
        }
        @media (prefers-reduced-motion: reduce) {
            .profile-avatar-enter,
            .profile-card-enter,
            .profile-saved-flash {
                animation: none !important;
            }
            .profile-avatar-btn:active { transform: none; }
            .profile-sync-spin { animation-duration: 2s; }
        }
        .pulse-accent {
            animation: pulseAlert 2s infinite ease-in-out;
        }
        @keyframes pulseAlert {
            0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
            50% { box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); }
        }
        .pulse-wrong-accent {
            animation: pulseWrongAlert 2s infinite ease-in-out;
        }
        @keyframes pulseWrongAlert {
            0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
            50% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0.2); }
        }
        .pulse-spaced-accent {
            animation: pulseSpacedAlert 2.5s infinite ease-in-out;
        }
        @keyframes pulseSpacedAlert {
            0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4); }
            50% { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0.1); }
        }
        .animate-fire {
            animation: fireGlow 1.5s ease-in-out infinite;
            display: inline-block;
            vertical-align: middle;
            line-height: 1;
            transform-origin: center bottom;
            will-change: transform, filter;
            transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        }
        @keyframes fireGlow {
            0%, 100% { filter: drop-shadow(0 0 3px rgba(245, 158, 11, 0.5)); transform: scale(1); }
            50% { filter: drop-shadow(0 0 10px rgba(239, 68, 68, 0.8)); transform: scale(1.1); }
        }
        /* Intense interactive fire animations when daily target is met */
        .animate-fire-reached {
            animation: fireMilestoneActive 1.4s ease-in-out infinite;
            cursor: pointer;
            display: inline-block;
            vertical-align: middle;
            line-height: 1;
            will-change: transform, filter;
            transform-origin: center bottom;
            transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        }
        .animate-fire-reached:hover {
            transform: scale(1.5) rotate(15deg) !important;
            filter: drop-shadow(0 0 15px rgba(245, 158, 11, 1)) drop-shadow(0 0 25px rgba(239, 68, 68, 0.9)) saturate(1.8) !important;
        }
        .animate-fire-reached:active {
            transform: scale(0.95) rotate(-10deg) !important;
        }
        .fire-sparked {
            animation: fireInteractivePulse 0.75s cubic-bezier(0.175, 0.885, 0.32, 1.4) !important;
            display: inline-block;
            vertical-align: middle;
            line-height: 1;
        }
        @keyframes fireMilestoneActive {
            0% {
                transform: scale(1.15) translateY(0);
                filter: drop-shadow(0 0 6px rgba(245, 158, 11, 0.7)) drop-shadow(0 0 12px rgba(239, 68, 68, 0.5));
            }
            50% {
                transform: scale(1.28) translateY(-3px);
                filter: drop-shadow(0 0 14px rgba(245, 158, 11, 0.85)) drop-shadow(0 0 22px rgba(239, 68, 68, 0.7));
            }
            100% {
                transform: scale(1.15) translateY(0);
                filter: drop-shadow(0 0 6px rgba(245, 158, 11, 0.7)) drop-shadow(0 0 12px rgba(239, 68, 68, 0.5));
            }
        }
        @keyframes fireInteractivePulse {
            0% { transform: scale(1.15) rotate(0deg); }
            20% { transform: scale(2.3) rotate(18deg); filter: drop-shadow(0 0 25px rgba(245, 158, 11, 1)) drop-shadow(0 0 40px rgba(239, 68, 68, 0.9)) saturate(2.2); }
            50% { transform: scale(0.85) rotate(-8deg); }
            100% { transform: scale(1.15) rotate(0deg); }
        }
        /* Particle spark styles for interactive clicking */
        .fire-sparkle-particle {
            position: absolute;
            pointer-events: none;
            font-size: 14px;
            z-index: 10000;
            display: inline-block;
            animation: sparkBurst 1.1s cubic-bezier(0.12, 0.8, 0.32, 1) forwards;
        }
        @keyframes sparkBurst {
            0% { transform: translate(0, 0) scale(1.2) rotate(0deg); opacity: 1; }
            100% { transform: translate(var(--dx), var(--dy)) scale(0.2) rotate(var(--rot)); opacity: 0; }
        }
        /* Dynamic halo pulse shockwave for the fire icon */
        .fire-pulse-halo {
            position: absolute;
            pointer-events: none;
            width: 120px;
            height: 120px;
            border-radius: 50%;
            background: radial-gradient(circle, rgba(239, 68, 68, 0.6) 0%, rgba(245, 158, 11, 0.25) 50%, transparent 100%);
            z-index: 999;
            transform: translate(-50%, -50%) scale(0.2);
            opacity: 1;
            animation: fireHaloPulse 1s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;
        }
        @keyframes fireHaloPulse {
            0% { transform: translate(-50%, -50%) scale(0.2); opacity: 1; filter: blur(1px); }
            100% { transform: translate(-50%, -50%) scale(4); opacity: 0; filter: blur(4px); }
        }
        .hover-card-trigger {
            transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
        }
        .hover-card-trigger:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .widget-ghost {
            opacity: 0.5;
            border-style: dashed !important;
        }
        .badge-floating {
            animation: badgeFloat 3s ease-in-out infinite;
        }
        @keyframes badgeFloat {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-6px); }
        }
        /* Confetti elements */
        .confetti-piece {
            position: absolute; width: 8px; height: 8px; background: #ffd700;
            border-radius: 50%; opacity: 0.9; pointer-events: none;
            animation: confettiFly 2s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;
        }
        @keyframes confettiFly {
            from { transform: translate(0, 0) scale(1) rotate(0deg); opacity: 1; }
            to { transform: translate(var(--x), var(--y)) scale(0.3) rotate(360deg); opacity: 0; }
        }

        /* PREMIUM DYNAMIC THEMES STYLE PRESETS */
        :root {
            --ani-duration: 0.35s;
        }

        /* Transition variables override — scoped to active theme presets only */
        body.theme-minimal *, body.theme-pro *, body.theme-focus *, body.theme-classic * {
            transition-duration: var(--ani-duration);
        }

        /* 1. MINIMALIST THEME STYLE */
        body.theme-minimal {
            background-color: #fafafa !important;
            --bg: #fafafa;
            --card: rgba(255, 255, 255, var(--app-card-opacity, 1));
            --border: rgba(228, 228, 231, var(--app-card-opacity, 1));
        }
        /* The theme classes sit on <body> and `dark` on <html>, so the dark
           variants have to be written as descendants (the same shape the
           depth presets already use: `.dark body.ui-depth-subtle`). Written as
           `.dark.theme-minimal` they asked for both classes on ONE element and
           never matched, so the light `!important` background above stayed on
           in dark mode - a near-white page. */
        .dark body.theme-minimal {
            background-color: #09090b !important;
            --bg: #09090b;
            --card: rgba(24, 24, 27, var(--app-card-opacity, 1));
            --border: rgba(39, 39, 42, var(--app-card-opacity, 1));
        }
        body.theme-minimal .hover-card-trigger:hover {
            transform: none !important;
            box-shadow: none !important;
        }

        /* 2. GLASSMORPHIC PRO THEME STYLE */
        body.theme-pro {
            background: linear-gradient(135deg, #e0f2fe 0%, #f0fdf4 100%) !important;
            --bg: #f0fdf4;
        }
        .dark body.theme-pro {
            background: linear-gradient(135deg, #0f172a 0%, #022c22 100%) !important;
            --bg: #0f172a;
        }
        body.theme-pro .hover-card-trigger {
            /* removed heavy blur */
            -webkit-/* removed heavy blur */
            background: rgba(255, 255, 255, var(--app-card-opacity, 0.82)) !important;
            border-color: rgba(16, 185, 129, calc(var(--app-card-opacity, 0.82) * 0.18)) !important;
            box-shadow: 0 4px 20px -2px rgba(5, 150, 105, 0.05) !important;
        }
        .dark body.theme-pro .hover-card-trigger {
            /* removed heavy blur */
            -webkit-/* removed heavy blur */
            background: rgba(30, 41, 59, var(--app-card-opacity, 0.75)) !important;
            border-color: rgba(52, 211, 153, calc(var(--app-card-opacity, 0.75) * 0.13)) !important;
            box-shadow: 0 4px 25px -2px rgba(0, 0, 0, 0.3) !important;
        }

        /* 3. MENTAL FOCUS THEME STYLE */
        body.theme-focus {
            background-color: #fafaf9 !important;
            --bg: #fafaf9;
            --card: rgba(245, 245, 244, var(--app-card-opacity, 1));
            --border: rgba(231, 229, 228, var(--app-card-opacity, 1));
        }
        .dark body.theme-focus {
            background-color: #0c0a09 !important;
            --bg: #0c0a09;
            --card: rgba(28, 25, 23, var(--app-card-opacity, 1));
            --border: rgba(46, 42, 36, var(--app-card-opacity, 1));
        }
        body.theme-focus .page:not(.active) {
            filter: blur(8px) opacity(0.3);
        }
        body.theme-focus .page.active {
            filter: drop-shadow(0 20px 50px rgba(0,0,0,0.08)) !important;
        }

        /* Utility animations helper */
        @keyframes customPulseGlow {
            0%, 100% { box-shadow: 0 0 5px rgba(16, 185, 129, 0.2); }
            50% { box-shadow: 0 0 20px rgba(16, 185, 129, 0.6); }
        }
        .active-profile-glow {
            animation: customPulseGlow 3s infinite ease-in-out;
        }

        /* Heat-Wave Moving Background Gradient Animation */
        @keyframes heatwaveBg {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }
        .premium-streak-card {
            position: relative;
            background: linear-gradient(-45deg, var(--card), var(--card), #fef3c7, var(--card)) !important;
            background-size: 400% 400% !important;
            animation: heatwaveBg 15s ease infinite !important;
            overflow: hidden;
            border: 2px solid #f59e0b !important;
            box-shadow: 0 10px 25px -5px rgba(245, 158, 11, 0.15) !important;
            transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1) !important;
        }
        .dark .premium-streak-card {
            background: linear-gradient(-45deg, var(--card), var(--card), #78350f, var(--card)) !important;
            background-size: 400% 400% !important;
            border-color: #d97706 !important;
            box-shadow: 0 10px 30px -5px rgba(217, 119, 6, 0.3) !important;
        }
        .premium-streak-card:hover {
            transform: translateY(-4px) scale(1.01) !important;
            box-shadow: 0 20px 35px -5px rgba(245, 158, 11, 0.25) !important;
        }
        
        /* Premium learner badge with glowing shadow */
        .premium-badge {
            background: linear-gradient(135deg, #f59e0b 0%, #ef4444 100%);
            box-shadow: 0 0 12px rgba(245, 158, 11, 0.5);
            animation: badgePulse 2s infinite ease-in-out;
        }
        @keyframes badgePulse {
            0%, 100% { box-shadow: 0 0 8px rgba(245, 158, 11, 0.4); }
            50% { box-shadow: 0 0 18px rgba(239, 68, 68, 0.8); }
        }
        
        /* Glowing Fire effect */
        .glowing-fire-container {
            position: relative;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 48px;
            height: 48px;
            border-radius: 50%;
            background: rgba(245, 158, 11, 0.1);
            border: 1px solid rgba(245, 158, 11, 0.3);
            animation: fireHalo 2.5s infinite ease-in-out;
        }
        @keyframes fireHalo {
            0%, 100% { box-shadow: 0 0 5px rgba(245, 158, 11, 0.2); border-color: rgba(245, 158, 11, 0.2); }
            50% { box-shadow: 0 0 20px rgba(239, 68, 68, 0.6); border-color: rgba(239, 68, 68, 0.6); background: rgba(239, 68, 68, 0.15); }
        }

        /* Streak Count-Up Numbers Styling */
        .streak-number-glowing {
            background: linear-gradient(135deg, #f59e0b 0%, #ef4444 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            filter: drop-shadow(0 2px 4px rgba(245, 158, 11, 0.15));
        }
/* ==================== NEW FEAT: IN-APP TOAST SYSTEM ==================== */
        .newfeat_toast-container {
            position: fixed;
            z-index: 100005;
            display: flex;
            flex-direction: column;
            gap: 12px;
            pointer-events: none;
            transition: all 0.35s ease;
        }
        
        @media (max-width: 767px) {
            .newfeat_toast-container {
                top: calc(12px + env(safe-area-inset-top));
                left: 50%;
                transform: translateX(-50%);
                width: calc(100% - 32px);
                max-width: 440px;
                align-items: center;
            }
        }
        
        @media (min-width: 768px) {
            .newfeat_toast-container {
                top: 24px;
                right: 24px;
                width: 360px;
                align-items: flex-end;
            }
        }

        .newfeat_toast {
            width: 100%;
            padding: 14px 16px;
            border-radius: var(--radius-sm, 10px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            font-size: 13px;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: 12px;
            pointer-events: auto;
            opacity: 0;
            transform: translateY(-20px);
            transition: opacity 350ms cubic-bezier(0.16, 1, 0.3, 1), transform 350ms cubic-bezier(0.16, 1, 0.3, 1);
        }

        .newfeat_toast.newfeat_show {
            opacity: 1;
            transform: translateY(0);
        }
        .newfeat_toast.newfeat_hide {
            opacity: 0;
            transform: translateY(-15px) scale(0.95);
        }

        .newfeat_toast-success {
            background-color: #ecfdf5;
            color: #065f46;
            border-left: 5px solid #10b981;
        }
        .dark .newfeat_toast-success {
            background-color: #064e3b;
            color: #a7f3d0;
            border-left: 5px solid #10b981;
        }

        .newfeat_toast-info {
            background-color: #f0f9ff;
            color: #03496d; /* परिवर्तन गरिएको: उज्यालोमा सहजै पढ्न सकिने गाढा नीलो रङ */
            border-left: 5px solid #0284c7;
        }
        .dark .newfeat_toast-info {
            background-color: #0c4a6e;
            color: #bae6fd;
            border-left: 5px solid #38bdf8;
        }
        /* ==================== 2026 ULTRA-FUTURISTIC STYLES (Z-TOUCH LAYER) ==================== */
:root {
    --scroll-percent: 0;
}

/* GPU Isolation for Butterworth Smooth Rendering */
.hover-card-trigger, .page, #mcq-card-container, .option-btn, .modal-card-content {
    will-change: transform, opacity;
    transform-style: preserve-3d;
    backface-visibility: hidden;
}

/* Specular Light & Dynamic Laser Border Glow */
.premium-glow-card {
    position: relative;
    border-radius: var(--radius, 16px);
    background: var(--card);
    overflow: hidden;
    z-index: 1;
    border: 1px solid rgba(var(--primary-rgb), 0.15) !important;
}

.premium-glow-card::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: conic-gradient(
        from 0deg,
        transparent 0%,
        transparent 40%,
        var(--primary) 50%,
        transparent 60%,
        transparent 100%
    );
    animation: laserGlowBorder 5s linear infinite;
    z-index: -2;
    pointer-events: none;
}

.premium-glow-card::after {
    content: '';
    position: absolute;
    inset: 1px;
    background: var(--card);
    border-radius: calc(var(--radius, 16px) - 1px);
    z-index: -1;
    pointer-events: none;
}

@keyframes laserGlowBorder {
    100% {
        transform: rotate(360deg);
    }
}

/* Spring Mechanics Class Variables */
.spring-active {
    transition: transform 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.4s ease-out !important;
}

/* Scroll-driven Indicator Bar */
.futuristic-scroll-bar {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--primary) 0%, #3b82f6 100%);
    width: calc(var(--scroll-percent) * 100%);
    z-index: 100000;
    pointer-events: none;
    transition: width 0.1s ease-out;
}

/* 3D Container setup moved to specific elements to avoid breaking fixed positioning */
/* ==================== 2026 SIX FUTURISTIC ANIMATIONS STYLES ==================== */

/* १. बायो-मिमेटिक बाली वृद्धि एनिमेसनको बक्स */
.plant-growth-widget {
    position: absolute;
    top: 10px;
    right: 50px;
    width: 55px;
    height: 55px;
    background: rgba(255, 255, 255, 0.9);
    border: 1.5px solid var(--primary-light);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow);
    z-index: 10;
    transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.dark .plant-growth-widget {
    background: rgba(30, 41, 59, 0.9);
    border-color: var(--primary-dark);
}
.plant-growth-svg {
    width: 42px;
    height: 42px;
    transition: all 0.5s ease;
}
.withered-plant {
    transform: rotate(15deg) scale(0.9);
    filter: grayscale(0.6) sepia(0.2);
    opacity: 0.8;
}

/* २. द्रव प्रगति सूचक बार */
.irrigation-wave-container {
    position: relative;
    width: 100%;
    height: 8px;
    border-radius: 9999px;
    background: #cbd5e1;
    overflow: hidden;
}
.dark .irrigation-wave-container {
    background: #334155;
}
.irrigation-wave-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 9999px;
}
/* ==================== PREMIUM OVERLAY ANIMATIONS ==================== */
/* १. लहर फैलने एनिमेसन नियम */
.option-btn {
    position: relative !important;
    overflow: hidden !important;
}
.click-ripple {
    position: absolute;
    border-radius: 50%;
    background: rgba(var(--primary-rgb), 0.25);
    transform: scale(0);
    animation: ripple-wave 0.5s ease-out;
    pointer-events: none;
}
@keyframes ripple-wave {
    to {
        transform: scale(4);
        opacity: 0;
    }
}

/* २. अरोरा लाइट बग्ने नियम */
#home-active-profile-card {
    position: relative;
    overflow: hidden;
}
#home-active-profile-card::after {
    content: '';
    position: absolute;
    top: 0; left: 0; width: 40%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.22), transparent);
    transform: skewX(-25deg);
    animation: aurora-sweep 4.5s infinite ease-in-out;
    pointer-events: none;
}
.dark #home-active-profile-card::after {
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
}
@keyframes aurora-sweep {
    0% { transform: translateX(-150%) skewX(-25deg); }
    100% { transform: translateX(180%) skewX(-25deg); }
}

/* ३. बिरुवा हल्लिने नियम */
.plant-growth-widget {
    transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
}
.plant-growth-widget:hover, .plant-growth-widget:active {
    transform: scale(1.18) rotate(6deg) !important;
}

/* ३. मस्तिष्क-सञ्जाल शैलीको ज्ञान नक्सा */
.neural-mindmap-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius, 16px);
    padding: 16px;
    width: 100%;
    box-sizing: border-box;
    transition: transform 0.3s ease;
}
.neural-canvas {
    width: 100%;
    height: 180px;
    display: block;
    background: transparent;
}

/* ४. मौसम अनुकूल वातावरणीय पृष्ठभूमि क्यानभास */
#weather-ambient-canvas {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 30;
    pointer-events: none;
    opacity: 0.65;
}

/* ५. कन्सेप्ट स्क्यान लेजर बीम */
.specular-scan-beam-overlay {
    position: absolute;
    inset: 0;
    background: rgba(6, 78, 59, 0.1);
    z-index: 1000;
    pointer-events: none;
    overflow: hidden;
    border-radius: var(--radius, 16px);
    display: none;
}
.specular-laser-line {
    position: absolute;
    left: 0;
    width: 100%;
    height: 4px;
    background: linear-gradient(90deg, transparent, var(--primary) 50%, transparent);
    box-shadow: 0 0 25px var(--primary), 0 0 10px var(--primary), 0 0 35px rgba(16, 185, 129, 0.6);
    animation: sweepScanningBeam 2.5s ease-in-out infinite;
}
@keyframes sweepScanningBeam {
    0% { top: 0%; filter: brightness(1.2); }
    50% { top: 100%; filter: brightness(0.8); }
    100% { top: 0%; filter: brightness(1.2); }
}

/* ६. ३डी ऋतु चक्र र बाली चक्र कनवर्टर */
.seasonal-crop-wheel-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius, 16px);
    padding: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    transition: box-shadow 0.4s ease, border-color 0.4s ease;
}

@keyframes pulse-glow-blue {
    0% { box-shadow: 0 0 0px rgba(59, 130, 246, 0); border-color: var(--border); }
    30% { box-shadow: 0 0 25px rgba(59, 130, 246, 0.4); border-color: rgba(59, 130, 246, 0.45); }
    100% { box-shadow: 0 0 0px rgba(59, 130, 246, 0); border-color: var(--border); }
}
@keyframes pulse-glow-amber {
    0% { box-shadow: 0 0 0px rgba(245, 158, 11, 0); border-color: var(--border); }
    30% { box-shadow: 0 0 25px rgba(245, 158, 11, 0.4); border-color: rgba(245, 158, 11, 0.45); }
    100% { box-shadow: 0 0 0px rgba(245, 158, 11, 0); border-color: var(--border); }
}
@keyframes pulse-glow-green {
    0% { box-shadow: 0 0 0px rgba(16, 185, 129, 0); border-color: var(--border); }
    30% { box-shadow: 0 0 25px rgba(16, 185, 129, 0.4); border-color: rgba(16, 185, 129, 0.45); }
    100% { box-shadow: 0 0 0px rgba(16, 185, 129, 0); border-color: var(--border); }
}

.pulse-glow-kharif {
    animation: pulse-glow-blue 1.2s ease-out;
}
.pulse-glow-autumn {
    animation: pulse-glow-amber 1.2s ease-out;
}
.pulse-glow-winter {
    animation: pulse-glow-green 1.2s ease-out;
}
.crop-wheel-3d-wrapper {
    perspective: 1000px;
    width: 120px;
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    transform-style: preserve-3d;
}
.crop-wheel-circle {
    width: 110px;
    height: 110px;
    border-radius: 50%;
    border: 4px dashed var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 900;
    font-size: 13px;
    background: var(--primary-light);
    color: var(--primary-dark);
    transform-style: preserve-3d;
    transform: rotateX(24deg) rotateY(12deg) rotateZ(var(--crop-angle, 0deg));
    transition: transform 0.85s cubic-bezier(0.34, 1.56, 0.64, 1);
    box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15), inset 0 2px 5px rgba(255, 255, 255, 0.2);
}
.dark .crop-wheel-circle {
    background: var(--primary-dark);
    color: var(--primary-light);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.35), inset 0 1px 2px rgba(255, 255, 255, 0.05);
}

/* ८. एड्भान्स एनिमेसन कन्ट्रोलर रेन्ज इनपुट स्लाइडरहरू */
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #10b981;
    cursor: pointer;
    box-shadow: 0 0 6px rgba(16, 185, 129, 0.4);
    transition: transform 0.15s ease, background-color 0.15s;
}
input[type="range"]::-webkit-slider-thumb:hover {
    transform: scale(1.25);
    background: #059669;
}

/* ==================== NESTED CUSTOM STYLES ==================== */

#subject-buttons-container button:hover {
                        border-color: var(--primary);
                        background-color: var(--bg);
                    }

/* Animation styles for the upgraded gameplay */
                    .option-entrance {
                        opacity:0;
                        animation: optionEntranceAnim 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
                    }
                    @keyframes optionEntranceAnim {
                        from {
                            opacity: 0;
                            transform: translateY(8px) scale(0.98);
                        }
                        to {
                            opacity: 1;
                            transform: translateY(0) scale(1);
                        }
                    }
                    .glow-correct {
                        border-color: #10b981 !important;
                        background-color: rgba(16, 185, 129, 0.08) !important;
                        box-shadow: 0 0 12px rgba(16, 185, 129, 0.3) !important;
                        animation: elementGlow 0.5s ease-in-out;
                    }
                    .shake-wrong {
                        border-color: #ef4444 !important;
                        background-color: rgba(239, 68, 68, 0.08) !important;
                        animation: shakeElement 0.4s ease-in-out;
                    }
                    .option-tap {
                        transform: scale(0.97);
                        transition: transform 0.1s ease;
                    }
                    .float-feedback {
                        position: absolute;
                        font-size: 14px;
                        font-weight: 900;
                        pointer-events: none;
                        animation: floatUp 0.8s ease-out forwards;
                        z-index: 50;
                    }
                    @keyframes elementGlow {
                        0% { transform: scale(1); }
                        50% { transform: scale(1.02); }
                        100% { transform: scale(1); }
                    }
                    @keyframes shakeElement {
                        0%, 100% { transform: translateX(0); }
                        20%, 60% { transform: translateX(-6px); }
                        40%, 80% { transform: translateX(6px); }
                    }
                    @keyframes floatUp {
                        0% { opacity: 0; transform: translateY(0) scale(0.5); }
                        30% { opacity: 1; transform: translateY(-15px) scale(1.1); }
                        100% { opacity: 0; transform: translateY(-40px) scale(0.9); }
                    }
                    .timer-pulse {
                        animation: timerAttention 1s infinite alternate;
                    }
                    @keyframes timerAttention {
                        0% { transform: scale(1); }
                        100% { transform: scale(1.1); color: #ef4444; }
                    }

/* Upgraded Study Planner Specific Animations */
                @keyframes pulseSlow {
                    0%, 100% { transform: scale(1); opacity: 1; }
                    50% { transform: scale(1.03); opacity: 0.9; }
                }
                @keyframes glowFire {
                    0%, 100% { filter: drop-shadow(0 0 4px #fbbf24) drop-shadow(0 0 10px #f97316); }
                    50% { filter: drop-shadow(0 0 8px #fbbf24) drop-shadow(0 0 20px #ef4444); }
                }
                @keyframes slideUp {
                    from { opacity: 0; transform: translateY(12px); }
                    to { opacity: 1; transform: translateY(0); }
                }
                @keyframes ringProgress {
                    from { stroke-dashoffset: 283; }
                }
                .hover-scale {
                    transition: all 0.2s ease-in-out;
                }
                .hover-scale:hover {
                    transform: translateY(-2px);
                    box-shadow: var(--shadow);
                }
                .animate-slide-up { animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
                .animate-fire { animation: glowFire 2s infinite ease-in-out; }
                .animate-pulse-slow { animation: pulseSlow 3s infinite ease-in-out; }

/* ==================== PREMIUM 3D ANIMATION CANVAS STYLES ==================== */
#daily-target-3d-canvas {
    width: 48px;
    height: 48px;
    display: block;
}
.neural-canvas {
    width: 100%;
    height: 180px;
    display: block;
}
#carousel-3d-canvas {
    width: 100%;
    height: 100px;
    display: block;
}

/* ==================== HIGH PERFORMANCE MOBILE ANDROID OPTIMIZATIONS ==================== */
/* Hardware Accelerated CSS layers — forces GPU rasterization, eliminates paint lag */
.page, .modal-overlay, .sheet-panel, .section-page, button, a, .card, .pressable {
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    -webkit-perspective: 1000;
    perspective: 1000;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    will-change: transform, opacity;
}

/* Inertia touch scrolling on all scrollable elements for native fluid feel */
.overflow-y-auto, .overflow-y-scroll, main, .scroll-container {
    -webkit-overflow-scrolling: touch !important;
    scroll-behavior: smooth;
    overscroll-behavior-y: contain;
}

/* Fast click feedback without delay */
button, a, input, select, textarea {
    -webkit-tap-highlight-color: transparent !important;
    touch-action: manipulation;
}

/* Reduce rendering costs on budget mobile GPUs (like OPPO Adreno) */
@media (max-width: 768px) {
    * {
        text-shadow: none !important; /* Text shadow is extremely expensive in WebViews */
    }
    .shadow-lg, .shadow-xl, .shadow-2xl {
        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -1px rgba(0, 0, 0, 0.04) !important;
    }
}

/* ==================== PREMIUM HYBRID BOTTOM SHEET DRAWER SYSTEM ==================== */
.premium-hybrid-active #subject-modal-overlay,
.premium-hybrid-active #cloud-config-modal {
    align-items: flex-end !important; /* Align at the bottom of the screen */
    justify-content: center !important;
    padding: 0 !important;
}

.premium-hybrid-active #subject-modal-overlay > div,
.premium-hybrid-active #cloud-config-modal > div {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    border-bottom-left-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
    border-top-left-radius: 24px !important; /* Premium curved top corners */
    border-top-right-radius: 24px !important;
    max-height: 85vh !important;
    transform: translateY(100%) scale(1) !important; /* Start off-screen */
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease !important;
    padding-top: 1.5rem !important; /* Leave space for drag handle */
}

/* Slide up into viewport when overlay is not transparent (i.e. active) */
.premium-hybrid-active #subject-modal-overlay:not(.opacity-0) > div,
.premium-hybrid-active #cloud-config-modal:not(.hidden) > div {
    transform: translateY(0) scale(1) !important;
}

/* Visual Native Drag Handle overlay */
.premium-hybrid-active #subject-modal-overlay > div::before,
.premium-hybrid-active #cloud-config-modal > div::before {
    content: '' !important;
    display: block !important;
    width: 36px !important;
    height: 4px !important;
    background-color: var(--border) !important;
    border-radius: 2px !important;
    margin: 0 auto !important;
    position: absolute !important;
    top: 8px !important;
    left: 50% !important;
    transform: translateX(-50%) !important;
    opacity: 0.6 !important;
}

/* ==================== PREMIUM HYBRID SHOW/HIDE UTILITIES ==================== */
.premium-hybrid-show {
    display: none !important;
}

.premium-hybrid-active .premium-hybrid-show {
    display: flex !important;
}

.premium-hybrid-active .premium-hybrid-hide {
    display: none !important;
}

/* ==================== PREMIUM HYBRID OPTION BUTTON GLOWS ==================== */
/* Default styled option button in hybrid mode */
.premium-hybrid-active .option-btn {
    border-radius: 14px !important;
    border: 2px solid var(--border) !important;
    transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1) !important;
    background-color: var(--card) !important;
    padding: 14px 16px !important;
    box-shadow: 0 2px 0 0 var(--border) !important; /* Flat native look */
}

/* When selected */
.premium-hybrid-active .option-btn.selected {
    border-color: var(--primary) !important;
    background-color: rgba(var(--primary-rgb), 0.04) !important;
    box-shadow: 0 2px 0 0 var(--primary) !important;
    transform: translateY(1px) !important;
}

/* Correct Answer Glow (Emerald Pulse) */
.premium-hybrid-active .option-btn.glow-correct {
    border-color: #10b981 !important;
    background-color: rgba(16, 185, 129, 0.08) !important;
    color: #065f46 !important;
    box-shadow: 0 2px 8px 0 rgba(16, 185, 129, 0.3) !important;
    /* Play once — no perpetual loop on answered state */
    animation: hybridCorrectPulse 0.7s cubic-bezier(0.16, 1, 0.3, 1) 1 forwards !important;
}
.premium-hybrid-active.dark .option-btn.glow-correct {
    color: #34d399 !important;
}

/* Incorrect Answer Shake & Red Glow (Rose Red) */
.premium-hybrid-active .option-btn.shake-wrong {
    border-color: #ef4444 !important;
    background-color: rgba(239, 68, 68, 0.08) !important;
    color: #991b1b !important;
    box-shadow: 0 2px 8px 0 rgba(239, 68, 68, 0.3) !important;
    animation: hybridWrongShake 0.4s cubic-bezier(.36,.07,.19,.97) both !important;
}
.premium-hybrid-active.dark .option-btn.shake-wrong {
    color: #f87171 !important;
}

/* Animations Keyframes */
@keyframes hybridCorrectPulse {
    0% { transform: scale(1); }
    60% { transform: scale(1.015); box-shadow: 0 2px 14px 0 rgba(16, 185, 129, 0.45) !important; }
    100% { transform: scale(1.01); box-shadow: 0 2px 10px 0 rgba(16, 185, 129, 0.3) !important; }
}

@keyframes hybridWrongShake {
    10%, 90% { transform: translate3d(-2px, 0, 0); }
    20%, 80% { transform: translate3d(4px, 0, 0); }
    30%, 50%, 70% { transform: translate3d(-6px, 0, 0); }
    40%, 60% { transform: translate3d(6px, 0, 0); }
}

/* ==================== MOBILE LAYOUT RESPONSIVE & OVERLAP FIXES ==================== */
@media (max-width: 767px) {
    /* 1. Lift the floating Connect Mobile button above bottom nav bar (Commented out - overlays disabled)
    #mobile-qr-btn {
        bottom: 75px !important;
        right: 16px !important;
        padding: 10px 16px !important;
        font-size: 13px !important;
    }
    */

    /* 2. Lift PWA install banner above bottom nav bar (Commented out - overlays disabled)
    #pwa-install-banner {
        bottom: 75px !important;
        width: 94% !important;
        border-radius: 16px !important;
        padding: 12px 16px !important;
    }
    */

    /* 3. Ensure all pages have comfortable bottom padding to prevent content cutoff */
    .page {
        padding-bottom: calc(4.75rem + env(safe-area-inset-bottom, 12px)) !important;
    }
}

/* Bottom-nav clearance for the TABLET range (768–1023px).
   #mobile-bottom-nav is `lg:hidden`, so the floating nav is visible on ALL widths
   below 1024px — but the clearance rule above only covered ≤767px, leaving tablets
   with no bottom padding, so the nav overlapped the last content. This closes the gap.
   (≥1024px is handled by the desktop block below, where the nav is hidden.) */
@media (min-width: 768px) and (max-width: 1023px) {
    .page {
        padding-bottom: calc(4.75rem + env(safe-area-inset-bottom, 12px)) !important;
    }
}

/* ==================== DESKTOP HYBRID MASTER-DETAIL LAYOUT RULES ==================== */
@media (min-width: 1024px) {
    /* 1. Limit infinite stretching on pages for optimized readability */
    .page {
        max-width: 960px !important;
        margin-left: auto !important;
        margin-right: auto !important;
        padding-top: 1.5rem !important;
        padding-bottom: 2rem !important;
    }
    
    /* 2. Adjust body padding-bottom since bottom nav is hidden */
    body {
        padding-bottom: env(safe-area-inset-bottom) !important;
    }
}

/* ==================== ADVANCED MOBILE LAYOUT OPTIMIZATIONS ==================== */
/* 1. Glassmorphism & Safe Area Utilities */
.glass-nav {
    background: rgba(255, 255, 255, var(--app-card-opacity, 0.85)) !important;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}
.dark .glass-nav {
    background: rgba(30, 41, 59, var(--app-card-opacity, 0.85)) !important;
}
.safe-pt { padding-top: env(safe-area-inset-top) !important; }
.safe-pb { padding-bottom: env(safe-area-inset-bottom) !important; }

/* 2. Smart Scroll Auto-Hide */
.nav-transition {
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.header-hide {
    transform: translateY(-100%);
}


.bottom-nav-hide {
    transform: translateY(140%) !important;
}

/* macOS-style Floating Zoom Dock */
@media (max-width: 1023px) {
/* Removed mobile-bottom-nav floating dock styles to restore the original full-width bar */
}

/* Center FAB inactive state (stays white/slate-200 until active) */
#nav-btn-2:not(.dock-active) {
    color: #e2e8f0 !important;
}

@media (min-width: 1024px) {
    #mobile-bottom-nav {
        display: none !important;
    }
}

/* Auto-hide the floating bottom nav while an overlay/sub-tab modal is open, so the
   nav (z-index 99999) does not float over the dialog. Slides down + fades; the nav's
   own `transition-transform duration-300` animates it. Horizontal centering
   (translateX(-50%)) is preserved. Restored the instant the modal closes. */
#mobile-bottom-nav.bottom-nav-hidden {
    transform: translateY(140%) !important;
    opacity: 0 !important;
    pointer-events: none !important;
    transition: transform 0.28s ease-in-out, opacity 0.2s ease-in-out !important;
}

/* Auto-hide the top chrome (mobile header + stats ribbon) during a live MCQ quiz,
   the same way the bottom nav hides — for a full-screen practice/exam view. These
   sit at the very top in normal flow, so collapsing their height (not just a slide)
   reclaims the space and avoids a blank gap above the question. Restored the moment
   the quiz view closes. A dedicated class (not `.header-hide`) so the smart-scroll
   listener can't fight it. */
#mobile-header.quiz-chrome-hidden,
#stats-ribbon.quiz-chrome-hidden {
    max-height: 0 !important;
    min-height: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    border-width: 0 !important;
    opacity: 0 !important;
    overflow: hidden !important;
    pointer-events: none !important;
    transform: translateY(-100%) !important;
    transition: transform 0.28s ease-in-out, opacity 0.2s ease-in-out, max-height 0.28s ease-in-out, padding 0.28s ease-in-out !important;
}

.dock-item {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: center !important;
    position: relative;
    width: 38px !important;
    height: 38px !important;
    border-radius: 50% !important;
    background: rgba(0, 0, 0, 0.04) !important;
    border: none !important;
    /* Ultra-smooth hardware accelerated transitions running at 60fps/120Hz */
    transition: width 0.2s cubic-bezier(0.25, 0.8, 0.25, 1), 
                padding 0.2s cubic-bezier(0.25, 0.8, 0.25, 1), 
                background-color 0.2s cubic-bezier(0.25, 0.8, 0.25, 1), 
                border-radius 0.2s cubic-bezier(0.25, 0.8, 0.25, 1),
                transform 0.15s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
    cursor: pointer;
    overflow: hidden !important; /* Hide overflowing text label during width transitions */
    padding: 0 9px !important;
    min-height: auto !important;
}

.dark .dock-item {
    background: rgba(255, 255, 255, 0.06) !important;
}

.dock-item:active {
    transform: scale(0.85) !important;
}

.dock-item.dock-active {
    width: 96px !important;
    border-radius: 9999px !important;
    background: rgba(16, 185, 129, 0.15) !important;
    border: 1px solid rgba(16, 185, 129, 0.25) !important;
    padding: 0 12px !important;
}

.dark .dock-item.dock-active {
    background: rgba(16, 185, 129, 0.2) !important;
    border-color: rgba(16, 185, 129, 0.35) !important;
}

.dock-text {
    display: none;
    opacity: 0;
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-left: 6px;
    color: var(--primary);
    white-space: nowrap;
    transition: opacity 0.2s ease 0.08s;
}

.dock-item.dock-active .dock-text {
    display: inline-block !important;
    opacity: 1 !important;
}

.dock-item .text-base {
    font-size: 20px;
    transition: transform 0.15s ease;
}

.dock-item::after {
    content: '';
    position: absolute;
    bottom: 2px;
    left: 50%;
    transform: translateX(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: transparent;
    transition: background 0.3s ease, transform 0.3s ease;
}

.dock-item.dock-active::after {
    display: none !important;
}

.dock-tooltip {
    position: absolute;
    top: -38px;
    left: 50%;
    transform: translateX(-50%) scale(0.85);
    opacity: 0;
    pointer-events: none;
    background: rgba(15, 23, 42, 0.85);
    color: #fff;
    padding: 4px 10px;
    border-radius: 8px;
    font-size: 9px;
    font-weight: 700;
    white-space: nowrap;
    transition: opacity 0.18s cubic-bezier(0.25, 0.8, 0.25, 1), transform 0.18s cubic-bezier(0.25, 0.8, 0.25, 1);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}
.dark .dock-tooltip {
    background: rgba(255, 255, 255, 0.95);
    color: #0f172a;
}

.dock-item:hover .dock-tooltip,
.dock-item.dock-touch-active .dock-tooltip {
    opacity: 1;
    transform: translateX(-50%) scale(1);
}

/* 3. Touch Targets & Active States */
@media (max-width: 1024px) {
    button, .option-btn, select, input[type="text"], input[type="number"], .touch-target {
        min-height: 48px;
    }
    
    /* Smooth Active Feedback instead of Hover for Touch */
    .hover-scale {
        transition: transform 0.15s ease-out, background-color 0.2s;
    }
    .hover-scale:active {
        transform: scale(0.96);
    }
    
    /* Convert Centered Modals to Bottom Sheets on Mobile */
    .modal-bottom-sheet {
        align-items: flex-end !important;
    }
    .modal-bottom-sheet > div {
        width: 100% !important;
        max-width: 100% !important;
        margin: 0 !important;
        border-bottom-left-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        max-height: 82vh !important;
        overflow-y: auto !important;
        animation: slideUpSheet 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.1) forwards;
    }
    
    /* Fluid Typography for headings on mobile.
       Deliberately NOT !important: this is the fallback size for a heading that
       declares none. When a heading carries an explicit size utility that
       authored size wins, which is what makes a real type hierarchy possible. */
    h1 { font-size: clamp(1.25rem, 5vw, 1.5rem); }
    h2 { font-size: clamp(1.125rem, 4.5vw, 1.25rem); }
    
    /* Edge-to-edge content container adjustments */
    .page.active {
        padding-left: 0.75rem !important;
        padding-right: 0.75rem !important;
    }

    /* 2x2 grid container for short MCQ options */
    .options-container-grid {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        gap: 8px !important;
    }
    .options-container-grid > button {
        margin-top: 0 !important;
        margin-bottom: 0 !important;
    }

    /* Clean Mobile Header Spacing and Tactile Tap Feedback */
    #mobile-header {
        padding: 12px 16px !important;
    }
    #mobile-header button {
        min-width: 48px !important;
        min-height: 48px !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        border-radius: 12px !important;
        transition: background-color 0.2s, transform 0.15s !important;
    }
    #mobile-header button:active {
        transform: scale(0.95) !important;
        background-color: rgba(0, 0, 0, 0.05) !important;
    }
    .dark #mobile-header button:active {
        background-color: rgba(255, 255, 255, 0.08) !important;
    }

    /* Limit long question text heights to prevent vertical overflow */
    #q-text {
        max-height: 20vh !important;
        overflow-y: auto !important;
        padding-right: 4px !important;
    }
}

@keyframes slideUpSheet {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

/* ==================== ADAPTIVE DOM PRUNING SYSTEM ==================== */
.prunable-row {
    contain: layout style;
}
.prunable-row.is-out-of-view > * {
    display: none !important;
}

/* ==================== AMBIENT STUDY PLAYER SYSTEM ==================== */

/* Floating trigger bubble */
#ambient-bubble {
    position: fixed;
    bottom: calc(5rem + env(safe-area-inset-bottom) + 8px);
    right: 16px;
    z-index: 9990;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6366f1, #8b5cf6);
    box-shadow: 0 4px 20px rgba(99,102,241,0.45), 0 0 0 0 rgba(99,102,241,0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    animation: ambientPulse 3s ease-in-out infinite;
    -webkit-tap-highlight-color: transparent;
}
#ambient-bubble:active { transform: scale(0.9); }
#ambient-bubble.ambient-active {
    background: linear-gradient(135deg, #10b981, #059669);
    box-shadow: 0 4px 20px rgba(16,185,129,0.5), 0 0 0 0 rgba(16,185,129,0.4);
}
@keyframes ambientPulse {
    0%, 100% { box-shadow: 0 4px 20px rgba(99,102,241,0.45), 0 0 0 0 rgba(99,102,241,0.3); }
    50% { box-shadow: 0 4px 24px rgba(99,102,241,0.6), 0 0 0 8px rgba(99,102,241,0.0); }
}

/* Slide-up drawer */
#ambient-study-drawer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9991;
    background: rgba(15, 23, 42, 0.97);
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
    border-top-left-radius: 24px;
    border-top-right-radius: 24px;
    border-top: 1px solid rgba(255,255,255,0.08);
    padding: 0 0 calc(1.5rem + env(safe-area-inset-bottom)) 0;
    transform: translateY(0);
    transition: transform 0.38s cubic-bezier(0.32, 0.72, 0, 1);
    max-height: 80vh;
    overflow-y: auto;
}
#ambient-study-drawer.ambient-drawer-hidden {
    transform: translateY(110%);
}

/* Drawer handle bar */
.ambient-drawer-handle {
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: rgba(255,255,255,0.2);
    margin: 12px auto 0;
}

/* Drawer header */
.ambient-drawer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px 8px;
}
.ambient-drawer-title {
    font-size: 0.8rem;
    font-weight: 800;
    color: #f1f5f9;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.ambient-drawer-close {
    background: rgba(255,255,255,0.08);
    border: none;
    border-radius: 50%;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #94a3b8;
    font-size: 0.75rem;
    transition: background 0.2s;
}
.ambient-drawer-close:active { background: rgba(255,255,255,0.15); }

/* Sounds grid */
#ambient-sounds-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    padding: 8px 16px 16px;
}

/* Sound card */
.ambient-sound-card {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 14px;
    overflow: hidden;
    transition: border-color 0.2s, background 0.2s;
    cursor: pointer;
}
.ambient-sound-card.ambient-card-active {
    background: rgba(var(--accent-rgb, 99,102,241), 0.12);
    border-color: var(--accent, #6366f1);
    box-shadow: 0 0 12px rgba(var(--accent-rgb, 99,102,241), 0.2);
}
.ambient-card-top {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.ambient-card-icon { font-size: 1rem; flex-shrink: 0; }
.ambient-card-label { font-size: 0.65rem; font-weight: 700; color: #e2e8f0; flex: 1; line-height: 1.3; }
.ambient-remove-btn {
    font-size: 0.6rem;
    color: #ef4444;
    background: none;
    border: none;
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 4px;
    flex-shrink: 0;
}

/* Volume row */
.ambient-vol-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px 10px;
}
.ambient-vol-icon { font-size: 0.7rem; }
.ambient-vol-slider {
    flex: 1;
    height: 3px;
    border-radius: 2px;
    cursor: pointer;
    appearance: none;
    background: rgba(255,255,255,0.1);
    outline: none;
}
.ambient-vol-slider::-webkit-slider-thumb {
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--accent, #6366f1);
    cursor: pointer;
    box-shadow: 0 0 6px rgba(99,102,241,0.5);
}

/* Sleep timer row */
.ambient-timer-row {
    display: flex;
    gap: 8px;
    padding: 0 16px 8px;
    flex-wrap: wrap;
}
.ambient-timer-btn {
    flex: 1;
    min-width: 60px;
    padding: 7px 8px;
    border-radius: 10px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.05);
    color: #94a3b8;
    font-size: 0.6rem;
    font-weight: 700;
    cursor: pointer;
    text-align: center;
    transition: background 0.2s, color 0.2s;
}
.ambient-timer-btn:active { background: rgba(255,255,255,0.12); color: #f1f5f9; }

/* Custom sound add form */
.ambient-custom-form {
    padding: 8px 16px 4px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.ambient-custom-input {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 10px;
    padding: 8px 12px;
    font-size: 0.65rem;
    color: #e2e8f0;
    outline: none;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
}
.ambient-custom-input::placeholder { color: #475569; }
.ambient-custom-input:focus { border-color: #6366f1; background: rgba(99,102,241,0.08); }
.ambient-add-btn {
    width: 100%;
    padding: 9px;
    border-radius: 10px;
    background: linear-gradient(135deg, #6366f1, #8b5cf6);
    border: none;
    color: white;
    font-size: 0.65rem;
    font-weight: 800;
    cursor: pointer;
    transition: opacity 0.2s;
}
.ambient-add-btn:active { opacity: 0.8; }

/* Section label */
.ambient-section-label {
    font-size: 0.6rem;
    font-weight: 800;
    color: #475569;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 10px 16px 4px;
}

/* =====================================================================
   LAYOUT 5 — UNIFIED SHELL SYSTEM
   Stats Ribbon + Bottom Sheet + Enhanced Nav
   Zero impact on existing components.
   ===================================================================== */

/* ── Stats Ribbon ──────────────────────────────────────────────────── */
#stats-ribbon {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    height: 32px;
    padding: 0 16px;
    overflow: hidden;
    position: relative;
    z-index: 35;
    border-bottom: 1px solid var(--border);
    background: var(--nav-bg);
    transition: opacity 0.3s, height 0.3s;
}
#stats-ribbon.ribbon-hidden {
    height: 0;
    opacity: 0;
    border: none;
    pointer-events: none;
}
.ribbon-stat {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.6rem;
    font-weight: 800;
    white-space: nowrap;
    padding: 0 10px;
    color: var(--text-secondary);
    letter-spacing: 0.02em;
    position: relative;
}
.ribbon-stat + .ribbon-stat::before {
    content: '';
    position: absolute;
    left: 0;
    top: 25%;
    height: 50%;
    width: 1px;
    background: var(--border);
}
.ribbon-stat .ribbon-val {
    color: var(--text);
    font-weight: 900;
}
.ribbon-stat.ribbon-fire .ribbon-val { color: #f97316; }
.ribbon-stat.ribbon-check .ribbon-val { color: #10b981; }
.ribbon-stat.ribbon-book .ribbon-val { color: #6366f1; }

/* Ribbon scroll-hide: hide when scrolling down, show on up */
.ribbon-scroll-hidden {
    transform: translateY(-100%);
    transition: transform 0.25s ease;
}
.ribbon-scroll-visible {
    transform: translateY(0);
    transition: transform 0.25s ease;
}

/* ── Bottom Sheet Backdrop ──────────────────────────────────────────── */
#nav-sheet-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9980;
    background: rgba(0, 0, 0, 0);
    pointer-events: none;
    transition: background 0.3s ease;
}
#nav-sheet-backdrop.sheet-backdrop-active {
    background: rgba(0, 0, 0, 0.5);
    pointer-events: all;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}

/* ── Bottom Sheet Panel ─────────────────────────────────────────────── */
#nav-bottom-sheet {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 9981;
    background: var(--nav-bg);
    border-top-left-radius: 24px;
    border-top-right-radius: 24px;
    border-top: 1px solid var(--border);
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom));
    transform: translateY(110%);
    transition: transform 0.36s cubic-bezier(0.32, 0.72, 0, 1);
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.15);
    will-change: transform;
}
#nav-bottom-sheet.sheet-open {
    transform: translateY(0);
}

/* Sheet handle */
.sheet-handle {
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--border);
    margin: 12px auto 4px;
    cursor: pointer;
}

/* Sheet header */
.sheet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 20px 12px;
    border-bottom: 1px solid var(--border);
}
.sheet-header-title {
    font-size: 0.7rem;
    font-weight: 900;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.sheet-close-btn {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 50%;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 0.7rem;
    color: var(--text-secondary);
    transition: background 0.2s;
    -webkit-tap-highlight-color: transparent;
}
.sheet-close-btn:active { background: var(--border); }

/* Sheet nav grid */
.sheet-nav-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    padding: 16px;
}
.sheet-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 14px 8px;
    border-radius: 16px;
    border: 1px solid var(--border);
    background: var(--bg);
    cursor: pointer;
    transition: background 0.15s, transform 0.15s, border-color 0.15s;
    -webkit-tap-highlight-color: transparent;
    text-decoration: none;
    min-height: 72px;
    justify-content: center;
}
.sheet-nav-item:active {
    transform: scale(0.94);
    background: var(--card);
}
.sheet-nav-item.sheet-item-active {
    border-color: var(--primary);
    background: var(--primary-light);
}
.sheet-nav-item .sheet-icon {
    font-size: 1.25rem;
    line-height: 1;
}
.sheet-nav-item .sheet-label {
    font-size: 0.6rem;
    font-weight: 800;
    color: var(--text-secondary);
    text-align: center;
    line-height: 1.3;
}
.sheet-nav-item.sheet-item-active .sheet-label {
    color: var(--primary);
}

/* Sheet user info band */
.sheet-user-band {
    margin: 0 16px 0;
    padding: 12px 14px;
    border-radius: 14px;
    background: var(--bg);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
}
.sheet-user-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, #059669, #10b981);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    flex-shrink: 0;
}
.sheet-user-info { flex: 1; min-width: 0; }
.sheet-user-name {
    font-size: 0.7rem;
    font-weight: 900;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sheet-user-sub {
    font-size: 0.58rem;
    color: var(--text-secondary);
    font-weight: 600;
}

/* ── More Button active state in bottom nav ─────────────────────────── */
#nav-btn-more {
    position: relative;
}
#nav-btn-more .more-dot-active {
    position: absolute;
    top: 4px;
    right: 8px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--primary);
    display: none;
}
#nav-btn-more.more-btn-highlight .more-dot-active {
    display: block;
}
#nav-btn-more.more-btn-highlight .nav-more-icon {
    color: var(--primary);
}

/* ── Desktop Sidebar Stats Panel ───────────────────────────────────── */
#sidebar-stats-panel {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px;
    border-radius: 14px;
    border: 1px solid var(--border);
    background: var(--bg);
}
.sidebar-stat-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.sidebar-stat-label {
    font-size: 0.6rem;
    font-weight: 700;
    color: var(--text-secondary);
}
.sidebar-stat-value {
    font-size: 0.65rem;
    font-weight: 900;
    color: var(--text);
}

/* ── Premium Bi-directional Page Slide Transitions & Active Streak Flame ── */
.streak-on-fire {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #f97316 !important;
    text-shadow: 0 0 8px rgba(249, 115, 22, 0.65), 0 0 16px rgba(239, 68, 68, 0.4) !important;
    animation: flamePulse 1.2s infinite ease-in-out alternate;
}
.streak-on-fire::before {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(253,186,116,0.25) 0%, rgba(239,68,68,0) 70%);
    z-index: -1;
    animation: flameGlow 2s infinite linear;
    pointer-events: none;
}

@keyframes flamePulse {
    0% { transform: scale(1); filter: drop-shadow(0 0 2px #f97316); }
    100% { transform: scale(1.12); filter: drop-shadow(0 0 7px #ef4444) saturate(1.4); }
}
@keyframes flameGlow {
    0% { transform: rotate(0deg) scale(0.9); opacity: 0.5; }
    50% { transform: rotate(180deg) scale(1.2); opacity: 0.8; }
    100% { transform: rotate(360deg) scale(0.9); opacity: 0.5; }
}

.slide-in-right {
    animation: slideInRight 0.32s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
    will-change: transform, opacity;
}
.slide-in-left {
    animation: slideInLeft 0.32s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
    will-change: transform, opacity;
}

@keyframes slideInRight {
    from { transform: translateX(45px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}
@keyframes slideInLeft {
    from { transform: translateX(-45px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

.fade-in-transition {
    animation: fadeInTransition 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
    will-change: opacity;
}
@keyframes fadeInTransition {
    from { opacity: 0; }
    to { opacity: 1; }
}

.zoom-in-transition {
    animation: zoomInTransition 0.32s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
    will-change: transform, opacity;
}
@keyframes zoomInTransition {
    from { transform: scale(0.96); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.no-transition {
    animation: none !important;
}

/* ── Page Transition Style live preview (Premium Study Settings > Appearance) ──
   The preview cards sit inside the app shell, which puts a broad
   `transition: all .35s` on them. That would smear the opacity swap over the
   keyframes and make every style look like a slow cross-fade, so the cards opt
   out of transitions entirely and are driven purely by the real animation
   classes they borrow from the navigation system above. */
#page-transition-preview,
#page-transition-preview * {
    transition: none !important;
}

/* ── Outgoing page (exit leg) ──────────────────────────────────────────
   navigate() lifts the leaving page out of document flow onto position:fixed
   at the rect it already occupied, so it cannot stack under the incoming page
   and cannot be dragged around by the smooth scroll-to-top that runs at the
   same moment. The inline top/left/width/height come from getBoundingClientRect(). */
.page-exiting {
    position: fixed !important;
    z-index: 5;
    pointer-events: none;
    margin: 0 !important;
    overflow: hidden;
}

.page-exit-left {
    animation: pageExitLeft var(--page-exit) cubic-bezier(0.4, 0, 1, 1) forwards !important;
    will-change: transform, opacity;
}
.page-exit-right {
    animation: pageExitRight var(--page-exit) cubic-bezier(0.4, 0, 1, 1) forwards !important;
    will-change: transform, opacity;
}
.page-exit-fade {
    animation: pageExitFade var(--page-exit) ease-out forwards !important;
    will-change: opacity;
}
.page-exit-zoom {
    animation: pageExitZoom var(--page-exit) cubic-bezier(0.4, 0, 1, 1) forwards !important;
    will-change: transform, opacity;
}

@keyframes pageExitLeft {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(-28px); opacity: 0; }
}
@keyframes pageExitRight {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(28px); opacity: 0; }
}
@keyframes pageExitFade {
    from { opacity: 1; }
    to { opacity: 0; }
}
@keyframes pageExitZoom {
    from { transform: scale(1); opacity: 1; }
    to { transform: scale(1.03); opacity: 0; }
}

/* Staggered Content Animations for active pages.
   Applied by applyPageStagger() in js/app.js navigate() — the classes are put on
   the first few direct children of the page being entered, then stripped again.
   Timings are deliberately tight: the last staggered child must land before the
   user can reasonably act on the page (stagger-8 finishes at 0.63s). */
.page.active .stagger-1 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.03s both !important; will-change: transform, opacity; }
.page.active .stagger-2 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.07s both !important; will-change: transform, opacity; }
.page.active .stagger-3 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.11s both !important; will-change: transform, opacity; }
.page.active .stagger-4 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.15s both !important; will-change: transform, opacity; }
.page.active .stagger-5 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.19s both !important; will-change: transform, opacity; }
.page.active .stagger-6 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.23s both !important; will-change: transform, opacity; }
.page.active .stagger-7 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.27s both !important; will-change: transform, opacity; }
.page.active .stagger-8 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.31s both !important; will-change: transform, opacity; }
.page.active .stagger-9 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.35s both !important; will-change: transform, opacity; }
.page.active .stagger-10 { animation: staggerElegant 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) 0.39s both !important; will-change: transform, opacity; }

@keyframes staggerElegant {
    0% { opacity: 0; transform: translateY(10px) scale(0.985); }
    100% { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .page.active [class*="stagger-"] {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
    .page-exiting {
        display: none !important;
    }
}

/* Automatically hide the main header inside page-practice when gameplay or result screen is active to maximize viewport budget on mobile */
@media (max-width: 1023px) {
    #page-practice:has(#page-mcq:not(.hidden)) h2:first-of-type,
    #page-practice:has(#practice-result-panel:not(.hidden)) h2:first-of-type {
        display: none !important;
    }
}

/* ==================== 2026 ULTRA-PREMIUM GLASSMORPHIC OPACITY ENGINE OVERRIDES ==================== */
/* Ensure all hover cards and containers across all themes get high-fidelity frosted glass backdrop blur */
.hover-card-trigger {
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}

/* Apply premium frosted glass blur on sidebars & modal overlay panels */
aside {
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
    background: var(--nav-bg) !important;
}

/* Force high-specificity card opacity override on Tailwind solid white/slate elements */
#mcq-card-container,
#result-card-container,
#home-nepal-globe-card,
#page-practice .grid > div {
    background: var(--card) !important;
    border-color: var(--border) !important;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}

/* 
   Overlay Settings & Modal Dialog sheets:
   We enforce a highly opaque background (0.98) to completely block the underlying 
   page text from bleeding through. We use a heavier backdrop blur and shadow to isolate 
   the controls perfectly, resolving the layout overlap issue cleanly.
   We redefine --bg to a subtle semi-transparent background inside overlays so all inputs 
   and buttons inherit a cohesive, elegant styling automatically.
*/
#planner-settings-panel,
.modal-bottom-sheet > div {
    background: rgba(255, 255, 255, 0.98) !important;
    border-color: var(--border) !important;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
    box-shadow: 0 25px 60px -10px rgba(0, 0, 0, 0.25) !important;
    --bg: rgba(0, 0, 0, 0.035) !important;
}
.dark #planner-settings-panel,
.dark .modal-bottom-sheet > div {
    background: rgba(15, 23, 42, 0.98) !important;
    border-color: rgba(255, 255, 255, 0.08) !important;
    box-shadow: 0 25px 65px -10px rgba(0, 0, 0, 0.6) !important;
    --bg: rgba(255, 255, 255, 0.045) !important;
}

/* Increase the blur on the backdrop overlay when planner settings are active */
#planner-settings-overlay {
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
    background: rgba(0, 0, 0, 0.4) !important;
}

/* 
   Refined Settings Input Controls:
   Inside overlays, we replace harsh solid green/grey backgrounds with a subtle, 
   modern semi-transparent layer, custom rounded borders, and transition focus glows.
*/
#planner-settings-panel input,
#planner-settings-panel select,
#planner-settings-panel textarea,
.modal-bottom-sheet input,
.modal-bottom-sheet select,
.modal-bottom-sheet textarea,
#planner-settings-panel button[id^="intensity-"],
#planner-settings-panel label[class*="select-none"],
#planner-settings-panel button[id^="rest-day-"] {
    background: var(--bg) !important;
    border: 1px solid rgba(0, 0, 0, 0.08) !important;
    border-radius: 12px !important;
    color: var(--text) !important;
    transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1) !important;
}

.dark #planner-settings-panel input,
.dark #planner-settings-panel select,
.dark #planner-settings-panel textarea,
.dark .modal-bottom-sheet input,
.dark .modal-bottom-sheet select,
.dark .modal-bottom-sheet textarea,
.dark #planner-settings-panel button[id^="intensity-"],
.dark #planner-settings-panel label[class*="select-none"],
.dark #planner-settings-panel button[id^="rest-day-"] {
    background: rgba(255, 255, 255, 0.04) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

#planner-settings-panel input:focus,
#planner-settings-panel select:focus,
#planner-settings-panel textarea:focus,
.modal-bottom-sheet input:focus,
.modal-bottom-sheet select:focus,
.modal-bottom-sheet textarea:focus {
    border-color: var(--primary) !important;
    background: rgba(16, 185, 129, 0.04) !important;
    box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.12) !important;
}

/* GPU Optimization: Automatically disable heavy backdrop filters on low-end or struggling devices */
.fps-throttled *,
.fps-throttled *::before,
.fps-throttled *::after {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

/* ==================== PREMIUM GLASSMORPHIC RESTORATION MODAL ==================== */
#custom-confirm-modal-overlay {
    background: rgba(8, 12, 24, 0.48) !important;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}

.confirm-glass-card {
    background: rgba(255, 255, 255, 0.78) !important;
    border: 1px solid rgba(255, 255, 255, 0.6) !important;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.08), 
                inset 0 1px 0 rgba(255, 255, 255, 0.8) !important;
    /* removed heavy blur */
    -webkit-/* removed heavy blur */
}

.dark .confirm-glass-card {
    background: rgba(15, 23, 42, 0.78) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35), 
                inset 0 1px 0 rgba(255, 255, 255, 0.06) !important;
}

.study-target-glow {
    position: relative;
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(245, 158, 11, 0.15) 100%) !important;
    color: #f59e0b !important;
    animation: targetPulse 2.5s infinite ease-in-out;
}

.dark .study-target-glow {
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(245, 158, 11, 0.2) 100%) !important;
}

@keyframes targetPulse {
    0%, 100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4);
    }
    50% {
        transform: scale(1.06);
        box-shadow: 0 0 15px 4px rgba(245, 158, 11, 0.2);
    }
}

#custom-confirm-ok-btn {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
    box-shadow: 0 4px 14px rgba(16, 185, 129, 0.3) !important;
    color: #ffffff !important;
    border: none !important;
    transition: all 0.22s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
}

#custom-confirm-ok-btn:active {
    transform: scale(0.94) !important;
    box-shadow: 0 2px 6px rgba(16, 185, 129, 0.15) !important;
}

#custom-confirm-cancel-btn {
    background: rgba(241, 245, 249, 0.85) !important;
    border: 1px solid rgba(226, 232, 240, 0.85) !important;
    color: #475569 !important;
    transition: all 0.22s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
}

.dark #custom-confirm-cancel-btn {
    background: rgba(30, 41, 59, 0.85) !important;
    border: 1px solid rgba(51, 65, 85, 0.85) !important;
    color: #94a3b8 !important;
}

#custom-confirm-cancel-btn:active {
    transform: scale(0.94) !important;
}

/* ==================== REAL-TIME AUTOSAVE HUD & PROGRESS DASHBOARD ==================== */
@keyframes autosavePulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.5);
    }
    50% {
        box-shadow: 0 0 8px 3px rgba(16, 185, 129, 0.2);
    }
}

.autosave-glow-active {
    background-color: #10b981 !important;
    animation: autosavePulse 1.8s infinite ease-in-out !important;
}

@keyframes autosaveSyncPulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5);
    }
    50% {
        box-shadow: 0 0 8px 3px rgba(59, 130, 246, 0.2);
    }
}

.autosave-glow-syncing {
    background-color: #3b82f6 !important;
    animation: autosaveSyncPulse 1.2s infinite ease-in-out !important;
}

.modal-stats-dashboard {
    background: rgba(15, 23, 42, 0.03) !important;
    border: 1px solid rgba(0, 0, 0, 0.04) !important;
    border-radius: 18px !important;
    padding: 12px 14px !important;
    text-align: left !important;
}

.dark .modal-stats-dashboard {
    background: rgba(255, 255, 255, 0.02) !important;
    border: 1px solid rgba(255, 255, 255, 0.05) !important;
}

.modal-progress-bar-container {
    height: 6px !important;
    background: rgba(0, 0, 0, 0.05) !important;
    border-radius: 10px !important;
    overflow: hidden !important;
    position: relative !important;
}

.dark .modal-progress-bar-container {
    background: rgba(255, 255, 255, 0.08) !important;
}

.modal-progress-bar-fill {
    height: 100% !important;
    background: linear-gradient(90deg, #10b981, #14b8a6) !important;
    border-radius: 10px !important;
    transition: width 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
}





/* XP MICRO-ANIMATION */
.xp-micro-anim {
    position: fixed;  /* fixed so it's never clipped by a parent overflow:hidden */
    color: #10b981; /* Emerald 500 */
    font-weight: 900;
    font-size: 14px;
    letter-spacing: 0.03em;
    pointer-events: none;
    z-index: 999999;
    text-shadow: 0 0 12px rgba(16, 185, 129, 0.55), 0 2px 8px rgba(16, 185, 129, 0.3);
    animation: xpPopFloat 720ms cubic-bezier(0.12, 0.82, 0.15, 1) forwards;
    transform: translate(-50%, -50%);
    will-change: transform, opacity;
}

@keyframes xpPopFloat {
    0% {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.4);
    }
    12% {
        opacity: 1;
        transform: translate(-50%, -62%) scale(1.25);
    }
    28% {
        transform: translate(-50%, -72%) scale(1.0);
    }
    78% {
        opacity: 1;
        transform: translate(-50%, -105%) scale(1.0);
    }
    100% {
        opacity: 0;
        transform: translate(-50%, -122%) scale(0.88);
    }
}

/* ONE-SHOT BOUNCE — for Level-Up emoji, no infinite loop */
@keyframes oneShot-bounce {
    0%   { transform: translateY(0); }
    30%  { transform: translateY(-10px); }
    55%  { transform: translateY(-4px); }
    75%  { transform: translateY(-7px); }
    90%  { transform: translateY(-2px); }
    100% { transform: translateY(0); }
}

/* ==================== STEP 26: PREMIUM MICRO-INTERACTIONS ==================== */
button:not(:disabled):not(.disabled):not(.option-btn):not(.creator-tab):not([role="tab"]):active, .btn:not(:disabled):not(.disabled):active {
    scale: 0.96;
    transition: scale 0.12s cubic-bezier(0.4, 0, 0.2, 1);
}
.option-btn:not(:disabled):not(.disabled):active {
    scale: 0.97;
    transition: scale 0.1s cubic-bezier(0.4, 0, 0.2, 1);
}
div[id^="creator-panel-"]:not(.hidden), div[id^="settings-tab-"]:not(.hidden), div[id^="customizer-panel-"]:not(.hidden), div[id^="hybrid-dash-content-"]:not(.hidden), #practice-active-state-panels:not(.hidden), #practice-result-panel:not(.hidden) {
    animation: micro-tab-enter 0.22s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes micro-tab-enter {
    0% { opacity: 0; transform: translateY(6px); }
    100% { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    button:active, .btn:active, .option-btn:active {
        scale: 1 !important;
        transition: none !important;
    }
    div[id^="creator-panel-"]:not(.hidden), div[id^="settings-tab-"]:not(.hidden), div[id^="customizer-panel-"]:not(.hidden), div[id^="hybrid-dash-content-"]:not(.hidden), #practice-active-state-panels:not(.hidden), #practice-result-panel:not(.hidden) {
        animation: micro-fade-enter 0.2s ease-out forwards;
    }
}
@keyframes micro-fade-enter {
    0% { opacity: 0; }
    100% { opacity: 1; }
}


.suppress-micro-interactions button:active, .suppress-micro-interactions .btn:active, .suppress-micro-interactions .option-btn:active { scale: 1 !important; transition: none !important; }

/* =====================================================================
   HOME — VISUAL POLISH LAYER (presentation only)
   Everything below sets radius / spacing / weight / colour. No rule here
   changes layout flow, visibility, or any behaviour hook. Backgrounds and
   borders keep using --card / --border so the theme picker still owns them.
   ===================================================================== */

/* ── One radius and one elevation for every card on Home ──────────────
   Previously siblings mixed 12 / 16 / 24px radii and 14 / 16px padding,
   which is the single most visible "unfinished" cue on the page. */
.home-card,
#home-widgets-container .hover-card-trigger,
#home-widgets-container > .slide-up-card > div {
    border-radius: var(--r-card);
    box-shadow: var(--elev-1);
}
/* The primary surface of the page sits one step higher. */
.home-card-raised {
    box-shadow: var(--elev-2);
}
/* Match the padding of the injected widget cards to the static ones.
   Both now read the density token, so the two stay in step at every
   Layout Density setting. */
#home-widgets-container .hover-card-trigger {
    padding: var(--card-pad);
}
/* Keep the existing hover lift on the widget cards that already had one —
   the static cards deliberately get no new hover behaviour. */
#home-widgets-container .hover-card-trigger:hover {
    box-shadow: 0 10px 15px -3px rgba(15, 23, 42, 0.06), 0 4px 6px -2px rgba(15, 23, 42, 0.05);
}

/* ── Micro label ("ACTIVE EXAM TARGET", "EXAM HUB SHORTCUTS") ─────────
   10px at 700 with open tracking reads as a deliberate eyebrow; the old
   9px/900 read as shouting. */
.home-eyebrow {
    font-size: 10px;
    font-weight: var(--w-bold);
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

/* ── Level progress bar ───────────────────────────────────────────────
   The old track was slate-100 on white (invisible) with a neon glow on
   the fill. Slightly darker track, softer glow, clearer edges. */
.prog-track {
    box-shadow: inset 0 0 0 1px var(--hairline);
}
.prog-track .prog-bar-fill {
    box-shadow: 0 0 6px rgba(52, 211, 153, 0.35);
}

/* Home "Daily Tasks / Mock Exams" segmented control removed — its styling
   (#hybrid-dashboard-segmented) was deleted with the markup. */

/* ── Mobile header icon buttons ───────────────────────────────────────
   The tap targets were already 48px but had no resting surface, so the
   two glyphs read as loose emoji rather than controls. */
#mobile-header > div:last-child button {
    font-size: 17px;
    line-height: 1;
    background: rgba(15, 23, 42, 0.04);
}
.dark #mobile-header > div:last-child button {
    background: rgba(255, 255, 255, 0.06);
}

/* ── Stats ribbon ─────────────────────────────────────────────────────
   Label and value were both rendering at the same weight, so the numbers
   didn't read as data. Two weights, a hairline divider, a little more air. */
#stats-ribbon {
    height: 34px;
    gap: 2px;
}
.ribbon-stat {
    font-size: 10.5px;
    font-weight: var(--w-semibold);
    letter-spacing: 0.005em;
    padding: 0 11px;
    gap: 5px;
}
.ribbon-stat + .ribbon-stat::before {
    background: var(--hairline);
    top: 30%;
    height: 40%;
}
.ribbon-stat .ribbon-val {
    font-weight: var(--w-extrabold);
    font-variant-numeric: tabular-nums;
}

/* =====================================================================
   SURFACE, DEPTH & DENSITY CONTROLS
   (Home -> Customize Home -> Appearance & Language)

   These <body> classes are written by applySurfaceStyleSettings() in
   js/app.js from the saved krishi_custom_appearance_settings object, the
   same way the theme presets already work. Keeping the values in CSS is
   what lets each step keep its own light and dark variant.

   The default step of every control ("Balanced" / "Comfortable") maps to
   the values already declared in :root, so an install that has never
   opened these selects renders byte-for-byte what it renders today.
   Nothing below changes layout flow, visibility or behaviour: radius,
   shadow, padding and font-weight only.
   ===================================================================== */

/* ── 1. Heading contrast (strength of the type hierarchy) ─────────────
   The ladder is re-declared rather than nudged through a single "step"
   variable, because a custom property is resolved where it is declared:
   a descendant cannot retroactively change the maths of an inherited
   one. Offsets stay on multiples of 100 so every step lands on a weight
   the bundled fonts actually ship. The Font Weight select
   (--app-font-weight) still shifts the whole ladder exactly as before. */
body.ui-hier-soft {
    --w-medium:    clamp(400, calc(var(--app-font-weight, 400) + 100), 600);
    --w-semibold:  clamp(500, calc(var(--app-font-weight, 400) + 100), 600);
    --w-bold:      clamp(500, calc(var(--app-font-weight, 400) + 200), 700);
    --w-extrabold: clamp(600, calc(var(--app-font-weight, 400) + 300), 700);
    --w-black:     clamp(700, calc(var(--app-font-weight, 400) + 300), 800);
}
body.ui-hier-strong {
    --w-medium:    clamp(500, calc(var(--app-font-weight, 400) + 100), 700);
    --w-semibold:  clamp(700, calc(var(--app-font-weight, 400) + 300), 800);
    --w-bold:      clamp(800, calc(var(--app-font-weight, 400) + 400), 900);
    --w-extrabold: clamp(900, calc(var(--app-font-weight, 400) + 500), 900);
    --w-black:     clamp(900, calc(var(--app-font-weight, 400) + 500), 900);
}

/* ── 2. Corner roundness ─────────────────────────────────────────────
   One radius per role, so sibling cards can never drift apart.

   --radius / --radius-sm are the older app-wide variables (generic cards,
   list rows, sidebar links). They are re-declared here so ONE control moves
   every corner in the app instead of Home cards only: :root declares them,
   this rule sits on <body>, and the nearer declaration wins for every
   descendant. Settings -> Appearance -> Round Corner Intensity now writes the
   same setting, so the two panels can no longer disagree. */
body.ui-corner-sharp    { --r-card:  8px; --r-control:  8px; --radius:  8px; --radius-sm:  6px; }
body.ui-corner-subtle   { --r-card: 13px; --r-control: 10px; --radius: 13px; --radius-sm:  8px; }
body.ui-corner-balanced { --r-card: 18px; --r-control: 12px; --radius: 18px; --radius-sm: 10px; }
body.ui-corner-soft     { --r-card: 24px; --r-control: 14px; --radius: 24px; --radius-sm: 14px; }
body.ui-corner-round    { --r-card: 28px; --r-control: 16px; --radius: 28px; --radius-sm: 18px; }

/* ── 3. Card depth ───────────────────────────────────────────────────
   "Balanced" is intentionally absent: it inherits the :root / .dark ramp.
   Cards keep their border in every step, so "Flat" still reads as a card. */
body.ui-depth-flat {
    --elev-1: none;
    --elev-2: none;
}
body.ui-depth-subtle {
    --elev-1: 0 1px 2px rgba(15, 23, 42, 0.04);
    --elev-2: 0 1px 3px rgba(15, 23, 42, 0.06);
}
body.ui-depth-elevated {
    --elev-1: 0 1px 2px rgba(15, 23, 42, 0.05), 0 6px 16px -6px rgba(15, 23, 42, 0.12);
    --elev-2: 0 2px 4px rgba(15, 23, 42, 0.06), 0 18px 36px -12px rgba(15, 23, 42, 0.20);
}
.dark body.ui-depth-subtle {
    --elev-1: 0 1px 2px rgba(0, 0, 0, 0.26);
    --elev-2: 0 2px 6px rgba(0, 0, 0, 0.34);
}
.dark body.ui-depth-elevated {
    --elev-1: 0 1px 2px rgba(0, 0, 0, 0.34), 0 8px 20px -6px rgba(0, 0, 0, 0.55);
    --elev-2: 0 2px 4px rgba(0, 0, 0, 0.34), 0 20px 40px -12px rgba(0, 0, 0, 0.70);
}

/* ── 4. Layout density ───────────────────────────────────────────────
   rem, not px, so density still compounds correctly with Font Size. */
body.ui-density-compact     { --card-pad: 0.75rem; --stack-gap: 0.625rem; }
body.ui-density-comfortable { --card-pad: 1rem;    --stack-gap: 0.875rem; }
body.ui-density-spacious    { --card-pad: 1.25rem; --stack-gap: 1.125rem; }

/* Cards on Home take their padding from the density token. The id in the
   selector is what lets this out-rank the p-4 utility in the markup. */
#page-home .home-card {
    padding: var(--card-pad);
}
/* Vertical rhythm of the Home stack. The markup's space-y-3.5 is 0.875rem,
   which is exactly the "Comfortable" value, so the default is unchanged. */
#page-home > :not([hidden]) ~ :not([hidden]) {
    margin-top: var(--stack-gap);
}

/* The customizer's own preview card mirrors the three surface controls, so
   corners, depth and density are visible before the user saves. */
#custom-live-preview-box {
    border-radius: var(--r-card);
    box-shadow: var(--elev-2);
    padding: var(--card-pad);
}

/* =====================================================================
   PRACTICE & RESULT — VISUAL POLISH LAYER (presentation only)
   Same contract as the HOME layer above: radius, elevation, padding,
   rhythm, weight and tint only. No rule here changes layout flow,
   visibility or a behaviour hook, and every value is read from the
   surface tokens (--r-card / --r-control / --radius-sm / --elev-* /
   --card-pad / --stack-gap), so Home -> Customize -> Appearance &
   Language now drives Practice and the Session Report exactly the way
   it already drives Home.
   Selectors are id-scoped on purpose: the Tailwind CDN injects its
   <style> after this file, so a plain class here would lose to an
   equally specific utility.
   ===================================================================== */

/* ── Section eyebrows ("⚡ Smart Practice Engine", "🕒 Recent ...") ────
   The four group labels rendered at 12px/700 with default tracking,
   which reads as body copy rather than as a label. Colour is left to
   the inline var(--text-secondary) that is already on the markup. */
#page-practice .section-eyebrow {
    font-size: 11px;
    font-weight: var(--w-bold);
    letter-spacing: 0.12em;
    line-height: 1.25;
    /* First declaration is the exact colour these headings used before
       (the theme's own secondary text token) and stays the value on any
       engine without color-mix. The second pulls the label a third of the
       way toward --text, which lifts 11px/700 from 4.1:1 to ~6:1 in light
       mode and does the same in dark, without inventing a new colour. */
    color: var(--text-secondary);
    color: color-mix(in srgb, var(--text-secondary) 65%, var(--text));
}

/* ── Vertical rhythm ─────────────────────────────────────────────────
   Practice stacks at space-y-4 (1rem) and the report at space-y-5
   (1.25rem) — 1.143x and 1.43x the "Comfortable" token. The ratio is
   kept instead of the absolute value, so the default renders exactly as
   it does today while Layout Density still moves both stacks. */
#page-practice > :not([hidden]) ~ :not([hidden]),
#practice-active-state-panels > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 1.143);
}
#practice-result-panel > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 1.43);
}

/* ── One radius + one elevation ladder for every Practice surface ─────
   Cards read --r-card, small tiles read --r-control and list rows read
   --radius-sm, so siblings can no longer disagree at any Corner
   Roundness setting. The padding multipliers reproduce today's
   p-3 / p-3.5 / p-4 / p-5 exactly at the "Comfortable" default. */
#page-practice #recommended-practice-banner,
#page-practice .practice-cta-card,
#page-practice #practice-empty-state,
#smart-engine-container .engine-tile,
#practice-result-panel #result-card-container,
#practice-result-panel .res-card {
    border-radius: var(--r-card);
    box-shadow: var(--elev-1);
}
#page-practice #recommended-practice-banner,
#page-practice .practice-cta-card,
#smart-engine-container .engine-tile,
#practice-result-panel .res-card {
    padding: var(--card-pad);
}
#page-practice #practice-empty-state,
#practice-result-panel #result-card-container {
    padding: calc(var(--card-pad) * 1.25);
}
#page-practice .practice-mode-tile,
#page-practice .practice-subject-card {
    border-radius: var(--r-control);
    box-shadow: var(--elev-1);
}
#page-practice .practice-mode-tile   { padding: calc(var(--card-pad) * 0.75); }
/* The tiles are flex rows (icon + text). Without min-width:0 the text
   column is sized by its longest word, so at 375px the second line of
   "Focus low-accuracy topics" ran past the tile edge and was clipped.
   This lets the caption wrap inside the tile instead. */
#page-practice .practice-mode-tile > div { min-width: 0; }
#page-practice .practice-subject-card { padding: calc(var(--card-pad) * 0.875); }
/* Subject-card footer: two 9px labels on one row. At 375px they do not
   both fit, and the browser was breaking them mid-phrase ("NOT /
   PRACTICED", "Configure / ➔"). Letting the row wrap keeps each label
   whole — one row on wide screens, two on a narrow phone. */
#page-practice .practice-subject-card .mt-3 {
    flex-wrap: wrap;
    gap: 0.25rem 0.5rem;
    min-width: 0;
}
#page-practice .practice-subject-card .mt-3 > span { white-space: nowrap; }
#practice-result-panel .res-tile     { border-radius: var(--r-control); }
#page-practice .practice-history-row { border-radius: var(--radius-sm); }

/* The two surfaces that already lift on hover keep doing so, one step up
   the same ladder — so "Flat" depth silences them too instead of leaving
   a hard-coded shadow behind. Nothing gains a NEW hover behaviour. */
#page-practice .practice-subject-card:hover,
#smart-engine-container .engine-tile:hover {
    box-shadow: var(--elev-2);
}

/* ── Tints the glass engine currently erases ──────────────────────────
   Two rules use the `background` SHORTHAND on these elements — the
   blanket "#page-practice .grid > div" rule further up, and the inline
   style="background:var(--card)" on the JS-built engine tiles — and a
   shorthand drops the gradient the markup declares, so four tinted
   surfaces render as plain cards today. Re-declaring the tint as
   `linear-gradient(tint), var(--card)` keeps the theme surface (and its
   opacity) underneath, so the frosted look and the tint coexist.
   Selector weight is deliberate: two ids, or class+class, is the least
   it takes to out-rank those two rules. */
#page-practice #sm2-dashboard-card,
#smart-engine-container .engine-tile.engine-tile--quick {
    background: linear-gradient(90deg, rgba(16, 185, 129, 0.10), rgba(20, 184, 166, 0.10)), var(--card) !important;
    border-color: rgba(16, 185, 129, 0.30) !important;
}
.dark #page-practice #sm2-dashboard-card,
.dark #smart-engine-container .engine-tile.engine-tile--quick {
    background: linear-gradient(90deg, rgba(6, 78, 59, 0.34), rgba(19, 78, 74, 0.34)), var(--card) !important;
}
#page-practice #hybrid-tinder-swiper-btn {
    background: linear-gradient(90deg, rgba(16, 185, 129, 0.08), rgba(20, 184, 166, 0.05)), var(--card) !important;
    border-color: rgba(16, 185, 129, 0.22) !important;
}
.dark #page-practice #hybrid-tinder-swiper-btn {
    background: linear-gradient(90deg, rgba(6, 78, 59, 0.22), rgba(19, 78, 74, 0.16)), var(--card) !important;
}
#smart-engine-container .engine-tile.engine-tile--mock {
    background: linear-gradient(90deg, rgba(99, 102, 241, 0.10), rgba(59, 130, 246, 0.10)), var(--card) !important;
    border-color: rgba(99, 102, 241, 0.28) !important;
}
.dark #smart-engine-container .engine-tile.engine-tile--mock {
    background: linear-gradient(90deg, rgba(49, 46, 129, 0.34), rgba(30, 58, 138, 0.30)), var(--card) !important;
}

/* ── Accent-coloured titles on Practice ──────────────────────────────
   These three labels are painted by the app-wide accent layer
   (.custom-accent-active ... { color: var(--primary) !important }), and
   the raw accent is 3.4:1 on a light card / 3.9:1 on a dark one at
   12px/900 — under AA either way, and the markup's dark:text-emerald-400
   never gets a chance because of that !important. Rather than re-tinting
   the shared accent layer (which would move every accent text in the
   app), the accent is nudged per surface here: the SAME hue the user
   picked, pushed toward black on light and toward white on dark. The
   plain var(--primary) line above each mix is the fallback for engines
   without color-mix, i.e. exactly today's colour. */
#page-practice #sm2-dashboard-card p:first-child,
#page-practice #hybrid-tinder-swiper-btn p:first-child,
#page-practice .practice-subject-card .mt-3 span:last-child {
    color: var(--primary) !important;
    color: color-mix(in srgb, var(--primary) 72%, #000000) !important;
}
.dark #page-practice #sm2-dashboard-card p:first-child,
.dark #page-practice #hybrid-tinder-swiper-btn p:first-child,
.dark #page-practice .practice-subject-card .mt-3 span:last-child {
    color: var(--primary) !important;
    color: color-mix(in srgb, var(--primary) 62%, #ffffff) !important;
}

/* ── Session Report stat tiles ───────────────────────────────────────
   Correct / Wrong / Skipped / Weighted Score are the one place on the
   page where colour carries meaning, so their tint is restored (the
   blanket rule flattened all four to var(--card)) and nudged from /5 to
   /7 with a visible border. Translucent on purpose: one declaration
   reads correctly on both the light and the dark surface. */
#practice-result-panel .res-tile.res-tile--correct {
    background: linear-gradient(rgba(16, 185, 129, 0.07), rgba(16, 185, 129, 0.07)), var(--card) !important;
    border-color: rgba(16, 185, 129, 0.22) !important;
}
#practice-result-panel .res-tile.res-tile--wrong {
    background: linear-gradient(rgba(244, 63, 94, 0.07), rgba(244, 63, 94, 0.07)), var(--card) !important;
    border-color: rgba(244, 63, 94, 0.22) !important;
}
#practice-result-panel .res-tile.res-tile--skipped {
    background: linear-gradient(rgba(100, 116, 139, 0.07), rgba(100, 116, 139, 0.07)), var(--card) !important;
    border-color: rgba(100, 116, 139, 0.20) !important;
}
#practice-result-panel .res-tile.res-tile--score {
    background: linear-gradient(rgba(99, 102, 241, 0.07), rgba(99, 102, 241, 0.07)), var(--card) !important;
    border-color: rgba(99, 102, 241, 0.22) !important;
}

/* ── Press feedback on the six Smart Practice tiles ───────────────────
   The markup asks for it with `active:scale-97`, but 97 is not in the
   Tailwind scale so nothing was ever generated and the tiles felt dead
   under the thumb. Implemented here with the same property, value ramp
   and easing the app already uses for buttons (see "PREMIUM
   MICRO-INTERACTIONS" above) — including the two switches that turn it
   off, since the tiles are <div>s and the button-only rules never
   reached them. */
#page-practice .practice-mode-tile:active {
    scale: 0.97;
    transition: scale 0.1s cubic-bezier(0.4, 0, 0.2, 1);
}
.suppress-micro-interactions #page-practice .practice-mode-tile:active {
    scale: 1;
    transition: none;
}
@media (prefers-reduced-motion: reduce) {
    #page-practice .practice-mode-tile:active {
        scale: 1;
        transition: none;
    }
}

/* ════════════════════════════════════════════════════════════════════
   QUIZ GAMEPLAY (#page-mcq) — VISUAL POLISH LAYER (presentation only)
   Same contract as the Practice layer above: no markup structure, no
   behaviour, no JS, no new features. Selectors are id-scoped because
   the Tailwind CDN injects its utility <style> AFTER this file, so a
   plain class rule here would lose to `.shadow-sm` / `.rounded-2xl`
   at equal specificity.

   Why it exists: the question card was the one large surface that
   ignored Home ▸ Customize ▸ Appearance & Language completely —
   radius was frozen at Tailwind's rounded-2xl (16px) while Corner
   asked for up to 28px, the shadow stayed shadow-sm whatever Depth
   said, and padding was pinned by an !important mobile rule whatever
   Density said.
   ════════════════════════════════════════════════════════════════════ */

/* Corner + Depth. `.rounded-2xl` and `.shadow-sm` are single-class
   utilities, so one id is enough to take the properties over. */
#mcq-card-container {
    border-radius: var(--r-card);
    box-shadow: var(--elev-1);
}

/* Density. The p-5 (1.25rem) look is preserved exactly at the default
   "Comfortable" (--card-pad: 1rem x 1.25 = 1.25rem); Compact and
   Spacious move it to 15px / 25px. Two ids + !important are needed
   only because the <=767px block near the top of this file pins this
   card to `padding: 1.25rem !important` ("3. Question Card sizing") —
   and 1.25rem is exactly what Comfortable still computes, so phones
   keep today's spacing unless the user changes Density on purpose. */
#page-mcq #mcq-card-container {
    padding: calc(var(--card-pad) * 1.25) !important;
}

/* Vertical rhythm. space-y-4 (1rem) on the page and on the card, and
   space-y-2.5 (0.625rem) between answer options, become multiples of
   --stack-gap. Both multipliers are picked so the default
   "Comfortable" (0.875rem) reproduces 1rem and 0.625rem exactly, i.e.
   nothing moves until the user changes Density.
   #q-options keeps its own <=767px margin (the "4. MCQ page spacing"
   block) on purpose — that is a deliberate mobile compaction. */
#page-mcq > :not([hidden]) ~ :not([hidden]),
#mcq-card-container > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 1.143);
}
#page-mcq #q-options > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 0.714);
}

/* Controls follow Corner as well, so nothing on the screen disagrees
   with anything else: answer buttons, the explanation panel and the
   three action buttons all read the same ladder as the card.
   The !important + 2 ids on .option-btn are what it takes to out-rank
   `.premium-hybrid-active .option-btn { border-radius: 14px !important }`
   and the <=767px `.option-btn { border-radius: 12px !important }` —
   the two hard-coded values that made Corner a no-op inside the quiz.
   var(--r-control) is 12px at the default Corner, which is what the
   phone rule already produced, so mobile is unchanged by default. */
#page-mcq #q-options .option-btn {
    border-radius: var(--r-control) !important;
}
#page-mcq #submit-btn,
#page-mcq #next-btn,
#page-mcq #finish-btn {
    border-radius: var(--r-control) !important;
}
#page-mcq #q-explanation {
    border-radius: var(--r-control);
}

/* ── The growth decoration was swallowing taps meant for ⚠️ Report ───
   #plant-growth-indicator is appended to this card by
   setupPlantAndIrrigationUI() as `position:absolute; top:10px;
   right:50px; z-index:10`, which lands it exactly on top of the badge
   / Hint / Report / bookmark row. Measured at 375px: plant occupied
   x257-312 y266-321 against the Report button's x258-319 y260-308, and
   document.elementFromPoint() at the button's own centre returned the
   plant's <svg> — so the tap never reached the button.

   Raising the control row one step above the decoration (it is z-index
   10, this is 11) is enough: the row does not move, the decoration
   does not move, and the plant keeps the hover/active wiggle it
   already has, because only the overlapping sliver changes hands.
   `pointer-events: none` on the plant would have fixed the tap too but
   would have silently deleted that wiggle, so it is not used. */
#mcq-card-container > div:first-child {
    position: relative;
    z-index: 11;
}

/* ==================================================================
   QUIZ GAMEPLAY (#page-mcq) — LAYOUT ADVANCE (presentation only)
   ------------------------------------------------------------------
   Five measured layout defects, all fixed without touching a single
   line of behaviour: no id is renamed, no element is removed, no JS
   handler is rebound, and every existing animation still runs.
   Measured at 320 / 375 / 1003 / 1280 px, hybrid mode ON (the
   default), against ui-corner-round / ui-depth-subtle /
   ui-density-spacious.
   ================================================================== */

/* ── 1. Reading column ───────────────────────────────────────────────
   `.page` already caps itself at 960px, but #page-mcq inherited the
   whole of it: measured at 1280px the question card was 896px wide and
   an answer button 844px, so a four-word option sat in a half-empty
   box and the question ran past 100 characters a line. Every other
   long-form page in the app already opts into a narrower column
   (#page-analytics uses max-w-4xl), so this follows that convention
   rather than inventing a new one.

   The width is a step on the EXISTING Density ladder instead of a new
   hard-coded number, so Home -> Customize -> Appearance & Language ->
   Density keeps control of it, exactly like --card-pad and
   --stack-gap. No new control, no new storage key. */
body                        { --quiz-col: 42rem; }
body.ui-density-compact     { --quiz-col: 38rem; }
body.ui-density-comfortable { --quiz-col: 42rem; }
body.ui-density-spacious    { --quiz-col: 46rem; }

@media (min-width: 768px) {
    /* margin-top is deliberately untouched — #page-practice's own
       space-y-4 owns it, and only the inline axis is centred here. */
    #page-practice > #page-mcq {
        max-width: var(--quiz-col);
        margin-left: auto;
        margin-right: auto;
    }
}

/* ── 2. One progress bar, not two ────────────────────────────────────
   #page-mcq stacks eight children, and in hybrid mode three of them
   are invisible but still charge a full space-y gap, because Tailwind's
   `> :not([hidden]) ~ :not([hidden])` matches on the ATTRIBUTE, so
   display:none siblings are still billed:

     #float-feedback-container   height 0  (absolute children only)
     the classic progress row    height 0  (all children premium-hybrid-hide)
     .irrigation-wave-container  height 8  (see below)

   Measured at 375px: the HUD ended at y272 and the question card began
   at y342 — 70px of gap holding one 8px empty bar.

   That bar is the classic-layout progress track. Its wrapper is marked
   `premium-hybrid-hide` in the markup, so it is meant to disappear in
   hybrid mode, but setupPlantAndIrrigationUI() reassigns
   `parent.className = 'irrigation-wave-container'` (js/app.js:15983),
   which overwrites the class string and takes premium-hybrid-hide with
   it — that is why a second, permanently-empty bar reappeared under the
   HUD. Restoring the author's intent in CSS keeps js/app.js untouched,
   and the rule is scoped to .premium-hybrid-active so CLASSIC mode
   still shows the bar and its water-wave canvas exactly as today. The
   canvas keeps drawing; only hybrid mode stops displaying it.

   Specificity notes: the two margin rules need 2-3 ids to out-rank our
   own `#page-mcq > :not([hidden]) ~ :not([hidden])` (1 id + 2 attrs);
   the display rule ties with it at 1 id + 2 classes and wins on order. */
#page-mcq > #float-feedback-container + #hybrid-duo-header {
    margin-top: 0;
}
.premium-hybrid-active #page-mcq > #hybrid-duo-header + div {
    margin-top: 0;
}
.premium-hybrid-active #page-mcq > .irrigation-wave-container {
    display: none;
    margin-top: 0;
}

/* ── 3. The sync pill stops being clipped ────────────────────────────
   The HUD row is `flex justify-between gap-3`: the ✕, a flex-1 bar, and
   the streak / hearts / autosave group. Nothing pinned the group, so it
   shared the shrink pressure with the bar. Measured at 1003px with the
   longest label js/app.js can write ("Local Only", 16679 / 16694 — the
   others are Ready / Saving... / Autosaved / Connected / Offline) the
   text ended at x971 against a container edge of x971: zero slack, and
   one pixel of pressure away from losing a character.

   Pinning the group and letting the bar absorb the shrink instead fixes
   it for every label at every width, without hiding the text and
   without touching the six strings js/app.js writes. */
#page-mcq #hybrid-duo-header > div:last-child {
    flex-shrink: 0;
}
#page-mcq #hybrid-duo-header > div:nth-child(2) {
    min-width: 2rem;
}
#page-mcq #game-autosave-indicator {
    white-space: nowrap;
}
/* The HUD is a white strip (`bg-white dark:bg-slate-900 py-1.5`) with
   horizontal padding of zero, so even un-clipped the last glyph of
   "Local Only" ended on the exact pixel the white surface ended —
   measured slack: 0px. A little inline padding is what makes it read as
   deliberate instead of cut off. */
#page-mcq #hybrid-duo-header {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

/* ── 4. The growth decoration stops colliding ────────────────────────
   The earlier z-index fix above made ⚠️ Report tappable again, but the
   two were still drawn on top of each other. Measured overlap with the
   original `top:10px; right:50px; 55x55`:
     1280px — plant x1110-1165 y304-359 vs Report x1106-1167 y304-321:
              the decoration covered the button end to end.
      375px — plant x237-292 y373-428 vs the EASY difficulty badge
              x228-267 y367-385: covered its right third.

   Fix is two-part and purely geometric. The decoration shrinks to 34px
   and moves to the true corner (right:8px), and the control row reserves
   a 46px lane so the ☆ / Report / Hint cluster can never slide back
   underneath it.

   The lane is NOT breakpoint-gated, and that is a measured decision. It
   was first written as `@media (min-width: 768px)` on the assumption that
   the row always wraps below that. It does not: at 480px the row fits on
   one line, `justify-between` pins the cluster to the right edge, and the
   34px decoration then sat completely on top of ☆ — measured overlap
   bookmark-btn x427-442 vs plant x425-459, 15x34px, i.e. the whole
   button. Applying the lane at every width costs the badges 46px of the
   row: at 375px they need 209px and still get 253px, so nothing is
   squashed and the wrap point does not move.

   Nothing interactive moves, nothing is hidden, and the plant keeps the
   hover/active wiggle it already has (.plant-growth-widget:hover
   { transform: scale(1.18) rotate(6deg) } at line 1068) — which is why
   `pointer-events: none` is still not used. The inline
   `transform: scale(...)` that updatePlantAndIrrigationState() writes on
   the inner <svg> for each growth stage is untouched: only the svg's
   CSS box shrinks with it, so all four stages still scale normally. */
#page-mcq #plant-growth-indicator {
    top: 10px;
    right: 8px;
    width: 34px;
    height: 34px;
}
#page-mcq #plant-growth-indicator .plant-growth-svg {
    width: 26px;
    height: 26px;
}
#page-mcq #mcq-card-container > div:first-child {
    padding-right: 46px;
}

/* ── 5. Answer options and question read as a hierarchy ──────────────
   Narrowing the column (1) already did the heavy lifting: an option
   goes from 844px to roughly 590px, so the text no longer floats in a
   half-empty box. Two small additions finish it.

   A hover tint tells you which option is under the cursor. It has to
   carry !important only because `.premium-hybrid-active .option-btn`
   pins border-color and background-color with !important; the extra ids
   and :not() guards keep it well clear of .selected, .disabled,
   .glow-correct and .shake-wrong, so no answer-state colour and no
   press animation (`.selected { transform: translateY(1px) }`) is
   affected. Non-hover behaviour is byte-identical.

   The question gains one step of size over the options so the eye lands
   on it first; it inherits its colour from the inline
   `style="color:var(--text)"` exactly as before. */
#page-mcq #q-options .option-btn:hover:not(.disabled):not(.selected):not(.glow-correct):not(.shake-wrong) {
    border-color: rgba(var(--primary-rgb), 0.5) !important;
    background-color: rgba(var(--primary-rgb), 0.04) !important;
}
#page-mcq #q-text {
    font-size: 1.0625rem;
    line-height: 1.6;
}

/* ============================================================
   QUIZ HELPERS — keyboard shortcuts, Question Map, 50:50
   Additive styling only. Every rule below targets markup that
   did not exist before (#quiz-assist-row, #quiz-map-modal,
   .option-eliminated, .quiz-map-*), so no existing quiz rule
   changes behaviour or looks.
   ============================================================ */

/* The helper row sits between the question card and the action
   buttons. display:flex lives here (not as a Tailwind `flex`
   class) so the [hidden] rule underneath can out-rank it with
   plain specificity, and so the row is driven by the `hidden`
   ATTRIBUTE: `#page-mcq > :not([hidden]) ~ :not([hidden])`
   above — and Tailwind's own space-y — both skip [hidden]
   siblings, while a .hidden CLASS would still be billed a gap.
   That phantom gap is the exact defect fixed in this screen
   earlier, so it must not come back through a new row. */
#page-mcq #quiz-assist-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}
/* The row is driven by [hidden]; .hidden is listed too so that a future
   caller using Tailwind's class still gets a hidden row instead of being
   silently out-ranked by the two-id display:flex above. */
#page-mcq #quiz-assist-row[hidden],
#page-mcq #quiz-assist-row.hidden,
#page-mcq #quiz-assist-row [hidden],
#page-mcq #quiz-assist-row .hidden,
#quiz-map-modal [hidden] {
    display: none !important;
}
/* Helpers follow the Corner ladder like every other control. */
#page-mcq #quiz-assist-row button {
    border-radius: var(--r-control, 12px);
}
/* A spent 50:50 stays visible but is clearly out of charges. */
.quiz-helper-spent {
    opacity: 0.4;
    pointer-events: none;
}

/* 50:50 removes nothing from the DOM — it dims two wrong options
   and takes their clicks away. !important beats the .option-entrance
   keyframes, which otherwise win over a plain opacity declaration. */
.option-eliminated {
    opacity: 0.28 !important;
    filter: grayscale(1);
    text-decoration: line-through;
    pointer-events: none;
    transition: opacity 0.25s ease, filter 0.25s ease;
}

/* A keyed answer gets the same "I registered that" nudge a tap gets. */
.option-keyed {
    animation: quizKeyFlash 0.24s ease;
}
@keyframes quizKeyFlash {
    0%   { transform: scale(1); }
    45%  { transform: scale(0.976); }
    100% { transform: scale(1); }
}

/* Question Map chips. Colours mirror the legend inside the modal.
   The column count is fluid rather than a fixed grid-cols-*, so a 10-question
   practice and a 100-question mock both stay one comfortable screen wide:
   ~9 columns inside the modal on a desktop, ~7 on a phone, chips ~40px either
   way — still a real tap target. */
#quiz-map-grid {
    grid-template-columns: repeat(auto-fill, minmax(2.25rem, 1fr));
}
.quiz-map-chip {
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--radius-sm, 10px);
    font-size: 11px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.quiz-map-chip:disabled {
    cursor: default;
}
.quiz-map-chip:not(:disabled):hover {
    transform: translateY(-1px);
    box-shadow: var(--elev-1, 0 1px 3px rgba(0, 0, 0, 0.12));
}
.quiz-map-chip:not(:disabled):active {
    transform: translateY(0) scale(0.96);
}

.quiz-map-correct  { background: rgba(16, 185, 129, 0.18); border-color: rgba(16, 185, 129, 0.55); color: #047857; }
.quiz-map-wrong    { background: rgba(244, 63, 94, 0.18);  border-color: rgba(244, 63, 94, 0.55);  color: #9f1239; }
.quiz-map-skipped  { background: rgba(245, 158, 11, 0.18); border-color: rgba(245, 158, 11, 0.55); color: #92400e; }
.quiz-map-answered { background: rgba(99, 102, 241, 0.18); border-color: rgba(99, 102, 241, 0.55); color: #3730a3; }
.quiz-map-upcoming { background: #f1f5f9; border-color: #cbd5e1; color: #64748b; }
.quiz-map-current  { background: #ffffff; border-color: var(--primary, #10b981); color: var(--text, #0f172a); }

.dark .quiz-map-correct  { color: #6ee7b7; }
.dark .quiz-map-wrong    { color: #fda4af; }
.dark .quiz-map-skipped  { color: #fcd34d; }
.dark .quiz-map-answered { color: #a5b4fc; }
.dark .quiz-map-upcoming { background: #334155; border-color: #475569; color: #cbd5e1; }
.dark .quiz-map-current  { background: #0f172a; }

/* Where the user actually is right now. */
.quiz-map-chip.quiz-map-now {
    box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 16, 185, 129), 0.55);
    border-color: var(--primary, #10b981);
}
/* Read-only review of one finished question. Built by JS with these
   classes only — no Tailwind `dark:` utilities are mixed in, so the
   panel follows the app theme (var(--text)) instead of the OS. */
.quiz-review-q {
    padding: 0.875rem;
    border: 1px solid var(--border);
    border-radius: var(--r-card, var(--radius, 16px));
    background: var(--card);
    color: var(--text);
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.55;
}
.quiz-review-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}
.quiz-review-opt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--border);
    border-radius: var(--r-control, 12px);
    background: var(--bg);
    color: var(--text);
}
.quiz-review-opt-text {
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.45;
}
.quiz-review-tag {
    flex: none;
    font-size: 9px;
    font-weight: 800;
    white-space: nowrap;
    opacity: 0.9;
}
.quiz-review-right      { background: rgba(16, 185, 129, 0.12); border-color: rgba(16, 185, 129, 0.5); }
.quiz-review-mine-wrong { background: rgba(244, 63, 94, 0.12);  border-color: rgba(244, 63, 94, 0.5); }
.quiz-review-mine       { background: rgba(99, 102, 241, 0.12); border-color: rgba(99, 102, 241, 0.5); }
.quiz-review-note {
    font-size: 10px;
    font-weight: 700;
    color: var(--text-secondary);
    line-height: 1.5;
}
.quiz-review-expl {
    padding: 0.75rem;
    border: 1px dashed var(--border);
    border-radius: var(--r-control, 12px);
    color: var(--text);
    font-size: 0.75rem;
    line-height: 1.55;
}
/* Direct child only: the explanation body below is now rich text, and a <strong> the user typed
   inside it must stay inline bold instead of being restyled as this block heading. */
.quiz-review-expl > strong {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}

/* ==========================================================================
   PROFILE (#page-profile) & SETTINGS (#page-settings)
   VISUAL POLISH LAYER (presentation only)
   --------------------------------------------------------------------------
   Same contract as the Home / Practice / Quiz layers above:

     * nothing here changes behaviour, markup, state or logic - only how the
       two pages are painted;
     * every value is read from a surface token that the Appearance &
       Language tab already writes (--r-card, --r-control, --elev-1,
       --card-pad, --stack-gap, --card, --border, --text, --text-secondary),
       so Corner / Depth / Density / Theme / Card Opacity / Text Colour all
       reach these pages exactly as they reach Home;
     * the multipliers are chosen so the DEFAULT setting reproduces today's
       pixel values (--stack-gap 0.875rem * 0.857 = 0.75rem = space-y-3,
       * 1.143 = 1rem = space-y-4), i.e. this layer is a no-op until the user
       actually moves a control.

   The five defects it fixes, measured on the live page:
     1. three different card radii on one screen (16 / 12 / 12px) that ignored
        the Corner control;
     2. Depth and Density were complete no-ops on both pages;
     3. 18 hardcoded bg-white + 12 dark:bg-slate-800 that ignored the theme
        palette and the Card Opacity slider;
     4. 59 captions painted at the literal #94a3b8 => 2.51:1 on white (AA
        fail), because .custom-text-active is only added for a non-default
        Text Colour;
     5. four list rows with no border-color, so they fell back to the
        preflight #e5e7eb instead of var(--border).

   Specificity notes that must be preserved when touching this block:
     * "#page-settings [id^=...] > div" = (1,1,1): beats .bg-white (0,1,0),
       .dark .bg-slate-800 (0,2,0) AND .rounded-xl - which is what lets the
       top-level cards take --r-card while the inner .rounded-xl controls
       still take --r-control;
     * the caption rule is (2,1,0) and the h3[class] title rule is (2,1,1),
       so titles always out-rank captions;
     * the tab :hover rule is (1,2,1), so it out-ranks the caption rule;
     * #settings-group-sound is deliberately LEFT OUT of the caption rule -
       the Ambient Player card paints its own #0f172a background and needs
       its own light-on-dark caption colour.
   ========================================================================== */

/* --- 1. Card shell: radius, elevation and surface come from the tokens ---- */
#page-profile > .profile-card-enter,
#page-settings [id^="settings-group-"] > div {
    border-radius: var(--r-card);
    box-shadow: var(--elev-1);
    background: var(--card);
}
#page-settings [id^="settings-group-"] > button {
    border-radius: var(--r-control);
    box-shadow: var(--elev-1);
    background: var(--card);
    border-color: var(--border);
}
/* Accordion trigger: a hair off the card so the header still reads as a
   header. First declaration is the fallback for engines without color-mix. */
#page-settings [id^="settings-group-"] > div > button {
    background: var(--bg);
    background: color-mix(in srgb, var(--text) 4%, var(--card));
}

/* --- 2. Density: padding ------------------------------------------------- */
#page-profile > .profile-card-enter,
#page-settings [id^="settings-group-"] > div > button,
#page-settings div[id^="accordion-body-"],
#page-settings #settings-group-visuals > div,
#page-settings #settings-group-general-bottom > div {
    padding: var(--card-pad);
}
#page-settings [id^="settings-group-"] > button {
    padding: calc(var(--card-pad) * 0.75);
}

/* --- 3. Density: vertical rhythm ----------------------------------------- */
/* space-y-3 on the page wrapper, space-y-3.5 inside the groups and space-y-4
   in the two visual groups, re-expressed through --stack-gap. The ID lifts
   these above Tailwind's own .space-y-* (0,3,0) rules. */
#page-profile > :not([hidden]) ~ :not([hidden]),
#page-settings > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 0.857);
}
#page-settings #settings-group-general > :not([hidden]) ~ :not([hidden]),
#page-settings div[id^="accordion-body-"] > :not([hidden]) ~ :not([hidden]) {
    margin-top: var(--stack-gap);
}
#page-settings #settings-group-sound > :not([hidden]) ~ :not([hidden]),
#page-settings #settings-group-visuals > :not([hidden]) ~ :not([hidden]),
#page-settings #settings-group-general-bottom > :not([hidden]) ~ :not([hidden]) {
    margin-top: calc(var(--stack-gap) * 1.143);
}

/* --- 4. Corner: inner surfaces follow the same ladder -------------------- */
/* min() keeps a nested surface from ever out-curving the card that holds it. */
#page-profile .rounded-2xl,
#page-settings .rounded-2xl {
    border-radius: min(16px, var(--r-card));
}
#page-profile .rounded-xl,
#page-settings .rounded-xl {
    border-radius: var(--r-control);
}

/* --- 5. Caption / title contrast ----------------------------------------- */
/* The captions were painted by Tailwind's literal .text-slate-400 (#94a3b8),
   which is 2.51:1 on white - an AA failure - and which also ignored the Text
   Colour setting, because js/app.js only adds .custom-text-active when that
   setting is NOT 'default'. Pulling --text-secondary partway towards --text
   fixes the contrast while keeping the secondary tone, and because both ends
   are tokens the result follows the theme, dark mode and the Text Colour
   setting on its own.

   --cap-mix is how much of the secondary colour survives the mix. A custom
   Text Colour palette pairs a saturated secondary with its own --text, and
   those are much lighter than slate (emerald's #34d399 is 1.92:1 on white),
   so for those palettes the mix leans further towards --text. Doing this with
   a variable - instead of a second, heavier selector - keeps the specificity
   ladder in this block intact. */
#page-profile,
#page-settings {
    --cap-mix: 55%;
}
body.custom-text-active #page-profile,
body.custom-text-active #page-settings {
    --cap-mix: 35%;
}
/* First declaration is the pre-color-mix fallback (4.76:1, still an
   improvement); the second is the real value. */
#page-profile :is(.text-slate-400, .text-slate-500),
#page-settings > div > .text-slate-500,
#page-settings :is(#settings-group-general, #settings-group-visuals, #settings-group-general-bottom) :is(.text-slate-400, .text-slate-500, .text-gray-400) {
    color: var(--text-secondary) !important;
    color: color-mix(in srgb, var(--text-secondary) var(--cap-mix, 55%), var(--text)) !important;
}
/* Settings tab strip: the inactive tabs are .text-slate-500 too, so the
   caption rule above would flatten their hover state. (1,2,1) restores it. */
#page-settings > div > .text-slate-500:hover {
    color: var(--text) !important;
}
/* Three group titles were shipped at caption colour (.text-slate-400). They
   are headings, so they take the full --text. (2,1,1) - above the captions. */
#page-profile h3[class],
#page-settings :is(#settings-group-general, #settings-group-visuals, #settings-group-general-bottom) h3[class] {
    color: var(--text) !important;
}

/* --- 6. Destructive row reads as destructive ----------------------------- */
/* Hard Reset sits in a stack of identical neutral rows; its text was already
   red, the outline now matches instead of falling back to var(--border). */
#page-settings #settings-group-general-bottom > button[onclick^="resetAllData"] {
    border-color: rgba(244, 63, 94, 0.45);
}

/* ==========================================================================
   DARK-MODE ACCENT + HOME CUSTOMIZER CONTRAST (presentation only)
   --------------------------------------------------------------------------
   Same contract as the layers above: no markup, state or logic changes.

   The accent layer near the top of this file maps Tailwind's emerald/indigo
   utilities onto the accent the user picked, with !important. That !important
   also beats the markup's own `dark:` variant, so in dark mode:

     * `text-emerald-600 dark:text-emerald-400` painted the RAW accent
       (#059669 by default) instead of emerald-400 - measured 3.9:1 on the
       dark card, an AA failure;
     * `bg-emerald-50 dark:bg-emerald-950/20` painted --primary-light
       (#d1fae5), i.e. a near-WHITE panel in dark mode, because the rule that
       was meant to catch this was written `.custom-accent-active .dark ...`
       and `dark` lives on <html>, an ancestor of <body>, so it never matched.

   Both are corrected here rather than by re-tinting the shared accent layer,
   which would move every accent surface in the app. The nudge is the same
   idiom the Practice layer already uses: the SAME hue the user picked, pushed
   toward white for a dark surface. The plain var(--primary) line above each
   mix is the fallback for engines without color-mix.
   ========================================================================== */

/* --- 1. Accent text on a dark surface ------------------------------------ */
.dark .custom-accent-active .text-emerald-600,
.dark .custom-accent-active .text-emerald-500,
.dark .custom-accent-active .text-emerald-700,
.dark .custom-accent-active .text-indigo-600,
.dark .custom-accent-active .text-indigo-700 {
    color: var(--primary) !important;
    color: color-mix(in srgb, var(--primary) 62%, #ffffff) !important;
}

/* --- 2. Accent tint panels on a dark surface ----------------------------- */
/* Mirrors the .bg-emerald-950/20 mapping, for the panels whose markup has no
   dark: counterpart at all. */
.dark .custom-accent-active .bg-emerald-50,
.dark .custom-accent-active .bg-indigo-50 {
    background-color: rgba(var(--primary-rgb), 0.15) !important;
}

/* --- 3. Home customizer captions ----------------------------------------- */
/* 38 labels/captions at .text-slate-400 and 23 at .text-slate-500 inside the
   customizer, with no dark: variant, so they were the literal #94a3b8 =
   2.51:1 on the white sheet. Same token mix (and the same --cap-mix escape
   hatch for custom Text Colour palettes) as the Profile/Settings layer.
   Buttons are included on purpose: the tab strip and the widget category
   chips mark their active state with a background, a heavier weight and a
   different text class, so lifting the INACTIVE ones cannot flatten it. */
#home-customizer-modal {
    --cap-mix: 55%;
}
body.custom-text-active #home-customizer-modal {
    --cap-mix: 35%;
}
#home-customizer-modal :is(.text-slate-400, .text-slate-500) {
    color: var(--text-secondary) !important;
    color: color-mix(in srgb, var(--text-secondary) var(--cap-mix, 55%), var(--text)) !important;
}

/* ==========================================================================
   Rich question text
   ==========================================================================
   Added by setRichTextContent() on any element it fills with a question's q.qHtml /
   q.explHtml instead of the plain text. Two things make this necessary: Tailwind's
   preflight zeroes <p> margins, so paragraphs would run together, and the sanitiser
   strips every attribute - including the classes Quill uses to mark its own list
   items - so a list would otherwise lose its markers and its indent. */
.rich-text-body > p { margin: 0; }
.rich-text-body > p + p { margin-top: 0.45em; }
.rich-text-body ul,
.rich-text-body ol {
    margin: 0.3em 0;
    padding-left: 1.35em;
    text-align: left;
}
.rich-text-body ul { list-style: disc outside; }
.rich-text-body ol { list-style: decimal outside; }
.rich-text-body li { margin: 0.15em 0; }
.rich-text-body b,
.rich-text-body strong { font-weight: 800; }
.rich-text-body u { text-underline-offset: 2px; }

/* ==================== MOBILE PERFORMANCE OVERRIDES ==================== */
/* Disable expensive backdrop filters and complex shadows on mobile devices 
   This prevents GPU overheating and massive battery drain on low-to-mid-tier phones.
*/
@media (max-width: 768px) {
    *, ::before, ::after {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }
}

/* DOM Pruner Virtualization */
.is-out-of-view {
    content-visibility: hidden;
}
.is-out-of-view > * {
    display: none !important;
}

/* 
 * ==========================================
 * ULTIMATE TRAIN PROGRESSION & UNIFIED HERO
 * ==========================================
 */
:root {
    /* Train Base Palette */
    --t-prim: #1d4ed8; 
    --t-sec: #1e3a8a;
    --t-dark: #0f172a;
    --t-acc: #38bdf8;
    --t-gold: #f59e0b;
    /* Wheel Palette */
    --w-rim: #334155;
    --w-tread: #94a3b8;
    --w-spoke: #475569;
    --w-hub: #1e293b;
    --w-glow: rgba(56, 189, 248, 0);
}

.unified-hero-card {
    background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
    border: 1px solid rgba(226, 232, 240, 0.8);
    box-shadow: 0 10px 25px -5px rgba(15, 23, 42, 0.05), 0 4px 10px -5px rgba(15, 23, 42, 0.02);
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease;
}
.dark .unified-hero-card {
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    border: 1px solid rgba(51, 65, 85, 0.5);
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 4px 10px -5px rgba(0, 0, 0, 0.2);
}
.unified-hero-card:hover {
    box-shadow: 0 15px 35px -5px rgba(15, 23, 42, 0.1);
}
.dark .unified-hero-card:hover {
    box-shadow: 0 15px 35px -5px rgba(0, 0, 0, 0.4);
}

.svg-wrapper {
    width: 100%;
    height: 120px;
    border-radius: 12px;
    overflow: hidden;
    position: relative;
    box-shadow: inset 0 2px 10px rgba(0,0,0,0.1);
}
.dark .svg-wrapper {
    box-shadow: inset 0 2px 15px rgba(0,0,0,0.5);
}

.overlay-text {
    position: absolute;
    top: 6px;
    font-size: 10px;
    font-weight: 800;
    color: rgba(15, 23, 42, 0.75);
    z-index: 10;
    text-shadow: 0 1px 2px rgba(255,255,255,0.8);
}
.dark .overlay-text {
    color: rgba(248, 250, 252, 0.85);
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}
.tl { left: 10px; }
.tr { right: 10px; }

svg#gameCanvas { display: block; width: 100%; height: 100%; }

/* Smooth Tier Color Transitions */
.tier-transition { transition: fill 1s ease, stroke 1s ease; }
.env-transition { transition: fill 2.5s ease, stop-color 2.5s ease, opacity 2.5s ease; }

/* Animations */
@keyframes wheel-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.wheel-large { transform-origin: 0 0; animation: wheel-spin 1s linear infinite; }
.wheel-small { transform-origin: 0 0; animation: wheel-spin 0.6s linear infinite; }

@keyframes scroll-bg { 0% { transform: translateX(0); } 100% { transform: translateX(-1000px); } }
#parallax-scroll-container, #poles-scroll-container, #foreground-scroll-container {
    animation: scroll-bg 12s linear infinite;
}
#foreground-scroll-container { animation-duration: 4s; }
#poles-scroll-container { animation-duration: 6s; }

@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } }


@keyframes piston-move { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-10px); } }
#piston-link, #piston-main { animation: piston-move 1s ease-in-out infinite; }

@keyframes cloud-move { 0% { transform: translateX(1000px) scale(var(--s)); } 100% { transform: translateX(-200px) scale(var(--s)); } }
.cloud-anim-1 { --s: 0.5; animation: cloud-move 40s linear infinite; }
.cloud-anim-2 { --s: 0.7; animation: cloud-move 25s linear infinite; }

.smoke-puff {
    fill: #cbd5e1;
    opacity: 0;
    transform-origin: center;
    animation: smoke-rise 2s ease-out forwards;
}
@keyframes smoke-rise {
    0% { transform: translate(-170px, -60px) scale(0.2); opacity: 0.6; }
    100% { transform: translate(-250px, -120px) scale(2.5); opacity: 0; }
}

.fg-blur { filter: blur(0.5px); }
.rain-drop {
    stroke: #93c5fd;
    stroke-width: 1.5;
    opacity: 0.6;
    animation: rain-fall linear infinite;
}
@keyframes rain-fall {
    0% { transform: translate(0, -150px); opacity: 0; }
    10% { opacity: 0.6; }
    90% { opacity: 0.6; }
    100% { transform: translate(-150px, 150px); opacity: 0; }
}

/* --- TRAIN SVG SPECIFIC STYLES --- */
:root {
    --t-prim: #78350f; --t-sec: #92400e; --t-dark: #292524;
    --t-gold: #a8a29e; --t-acc: #b45309;
    --w-rim: #44403c; --w-spoke: #78716c; --w-hub: #d6d3d1;
    --w-tread: #a8a29e; --w-glow: #f59e0b;
}

.svg-wrapper {
    position: relative; width: 100%; height: 90px; border-radius: 12px; overflow: hidden;
    box-shadow: inset 0 2px 10px rgba(0,0,0,0.15); border: 1px solid rgba(0,0,0,0.1);
}
.svg-wrapper svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }

.overlay-text { position: absolute; z-index: 20; font-size: 11px; font-weight: 800; text-shadow: 0 1px 3px rgba(255,255,255,1), 0 0 5px rgba(255,255,255,0.8); }
.tl { top: 8px; left: 12px; color: #047857; letter-spacing: 0.05em; text-transform: uppercase; }
.tr { top: 8px; right: 12px; color: #334155; }

.env-transition { transition: fill 2.5s ease-in-out, stop-color 2.5s ease-in-out, opacity 2.5s ease-in-out, stroke 2.5s ease-in-out; }
.tier-transition { transition: fill 1.5s ease, stop-color 1.5s ease, opacity 1.5s ease, stroke 1.5s ease; }
.passenger { transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease-out; }

@keyframes drift { from { transform: translateX(1000px); } to { transform: translateX(-200px); } }
@keyframes rainFall { 0% { transform: translateY(-50px) translateX(0px); opacity: 0; } 10% { opacity: 0.6; } 90% { opacity: 0.6; } 100% { transform: translateY(200px) translateX(-40px); opacity: 0; } }

@keyframes spin-reverse { 100% { transform: rotate(-360deg); } }
@keyframes pulse-glow { 0%, 100% { opacity: 0.7; filter: brightness(1); } 50% { opacity: 1; filter: brightness(1.5) drop-shadow(0 0 3px var(--t-acc)); } }
.inner-gear { animation: spin-reverse 3s linear infinite; transform-origin: 0px 0px; }
.hub-core { animation: pulse-glow 1.5s ease-in-out infinite; transform-origin: 0px 0px; }

@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
.passenger-bob { animation: bob 0.8s ease-in-out infinite; }

@keyframes cargo-pulse { 0%, 100% { filter: brightness(1) drop-shadow(0 0 4px var(--t-acc)); transform: scale(1); } 50% { filter: brightness(1.5) drop-shadow(0 0 12px var(--t-acc)); transform: scale(1.05); } }
.cargo-core { animation: cargo-pulse 1s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }

.fg-blur { filter: blur(1.5px); }
.cloud-anim-1 { animation: drift 40s linear infinite; }
.cloud-anim-2 { animation: drift 60s linear infinite 15s; }
.rain-drop { animation: rainFall 0.7s linear infinite; stroke: #93c5fd; stroke-width: 1.5; opacity: 0; stroke-linecap: round; }

/* Environment Animations */
@keyframes scroll-mid { from { transform: translateX(0); } to { transform: translateX(-1000px); } }
@keyframes scroll-fast { from { transform: translateX(0); } to { transform: translateX(-1000px); } }
@keyframes fly-bird { 0% { transform: translateY(0) scale(1); } 50% { transform: translateY(-5px) scale(0.9); } 100% { transform: translateY(0) scale(1); } }
@keyframes firefly-float { 0%, 100% { transform: translateY(0) translateX(0); opacity: 0.3; } 50% { transform: translateY(-15px) translateX(10px); opacity: 0.9; } }

.env-scroll-mid { animation: scroll-mid calc(15s / var(--train-speed, 1)) linear infinite; }
.env-scroll-fast { animation: scroll-fast calc(10s / var(--train-speed, 1)) linear infinite; }
.bird-fly { animation: fly-bird 1.5s ease-in-out infinite; }
.bird-1 { animation-delay: 0s; transform-origin: center; }
.bird-2 { animation-delay: 0.2s; transform-origin: center; }
.bird-3 { animation-delay: 0.4s; transform-origin: center; }
.firefly { animation: firefly-float 4s ease-in-out infinite alternate; }
.firefly-1 { animation-delay: 0s; } .firefly-2 { animation-delay: -1s; } .firefly-3 { animation-delay: -2s; } .firefly-4 { animation-delay: -3s; } .firefly-5 { animation-delay: -1.5s; } .firefly-6 { animation-delay: -2.5s; } .firefly-7 { animation-delay: -0.5s; }
.signal-red { animation: pulse-glow 2s infinite; }


.env-transition { transition: opacity 2.5s ease-in-out, fill 2.5s ease-in-out; }

/* ============================================================================
   🌾 3D MOUSE MASCOT — INTERACTIVE OVERLAY & ANIMATION SYSTEM
   ============================================================================ */
#mouse-overlay-container {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 99990;
    overflow: hidden;
}

#mouse-actor {
    position: absolute;
    width: 140px;
    height: 140px;
    pointer-events: auto;
    cursor: pointer;
    transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s ease;
    transform-origin: bottom center;
    opacity: 0;
    will-change: transform, opacity;
}

model-viewer#mascot-3d-model {
    width: 100%;
    height: 100%;
    --poster-color: transparent;
}

/* State 1: Walk Entrance from Right Edge (Steady Linear Walk) */
.mascot-walking-in {
    bottom: 18px;
    right: 25px;
    opacity: 1 !important;
    animation: walkInFromRight 1.6s linear forwards;
}

/* State 1B: Settled Peeking Idle */
.mascot-peeking {
    bottom: 18px;
    right: 25px;
    opacity: 1 !important;
    transform: translateX(0);
    animation: peekGentle 3s ease-in-out infinite alternate;
}

/* State 1C: Smooth Walk-Out Exit (Steady Linear Walk) */
.mascot-walk-out {
    bottom: 18px;
    right: 25px;
    opacity: 1 !important;
    animation: walkOutRight 1.4s linear forwards;
}

/* State 2: Running across bottom screen (Surprise Celebration) */
.mascot-running {
    bottom: 15px;
    opacity: 1 !important;
    animation: runAcrossSteady 2.5s linear forwards;
}

/* State 3: Scared run (Flinches/jumps first, then bolts to the right) */
.mascot-scare-run {
    bottom: 18px;
    right: 25px;
    opacity: 1 !important;
    animation: flinchAndRun 1.25s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes walkInFromRight {
    0% {
        transform: translateX(180px);
        opacity: 0;
    }
    15% {
        opacity: 1;
    }
    100% {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes walkOutRight {
    0% {
        transform: translateX(0);
        opacity: 1;
    }
    85% {
        opacity: 1;
    }
    100% {
        transform: translateX(180px);
        opacity: 0;
    }
}

@keyframes peekGentle {
    0% { transform: translateY(0) scale(1); }
    100% { transform: translateY(-4px) scale(1.02); }
}

@keyframes runAcrossSteady {
    0% {
        left: -160px;
        transform: translateX(0);
        opacity: 0;
    }
    10% {
        opacity: 1;
    }
    90% {
        opacity: 1;
    }
    100% {
        left: 100vw;
        transform: translateX(0);
        opacity: 0;
    }
}

@keyframes flinchAndRun {
    0% {
        transform: translateY(0) scale(1);
    }
    18% {
        transform: translateY(-28px) scale(1.15) rotate(-6deg);
    }
    32% {
        transform: translateY(0px) scale(1) rotate(0deg);
    }
    42% {
        transform: translateX(15px) translateY(0);
        opacity: 1;
    }
    100% {
        transform: translateX(280px) translateY(0);
        opacity: 0;
    }
}

/* --- Phoenix 3D Mascot & Trailing Banner CSS --- */
model-viewer#phoenix-model {
    width: 250px;  
    height: 250px;
    transform: scale(1.3);
    z-index: 10;
}

/* The Banner tied to the bird */
.trailing-banner {
    position: relative;
    background: #e74c3c;
    color: white;
    padding: 12px 24px; 
    font-size: 20px;    
    font-weight: bold;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
    box-shadow: 0 4px 10px rgba(0,0,0,0.3);
    border: 3px solid #f1c40f;
    border-radius: 5px;
    margin-right: 30px;
    opacity: 0;
    z-index: 5;
}

/* Ribbon tail on the left side of banner */
.trailing-banner::before {
    content: '';
    position: absolute;
    left: -20px;
    top: 0;
    border-top: 25px solid #e74c3c;
    border-bottom: 25px solid #e74c3c;
    border-left: 20px solid transparent;
}

/* Rope connecting banner to the bird's tail */
.trailing-banner::after {
    content: '';
    position: absolute;
    right: -35px;
    top: 50%;
    width: 35px;
    height: 3px;
    background-color: #bdc3c7;
    border-top: 1px dashed #7f8c8d;
    transform: translateY(-50%) rotate(5deg);
    z-index: -1;
}

/* Animations */
.phoenix-fly-across {
    animation: phoenixFlyAcross 6s linear forwards;
}

.phoenix-fade-in-banner {
    animation: bannerFadeIn 1s ease-in forwards, floatBanner 1.5s ease-in-out infinite alternate;
}

@keyframes phoenixFlyAcross {
    0% { transform: translateX(0) translateY(10vh); }
    50% { transform: translateX(65vw) translateY(-5vh); }
    100% { transform: translateX(130vw) translateY(5vh); }
}

@keyframes bannerFadeIn {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

@keyframes floatBanner {
    from { transform: translateY(-5px); }
    to { transform: translateY(5px); }
}

/* Practice mode: flush train animation to top edge with zero gap */
#practice-train-placeholder > #main-train-container {
    padding-top: 0 !important;
    margin-bottom: 0 !important;
    border-top: none !important;
}

/* Quiz active: hide heading, kill all top spacing so train is flush to top */
#page-practice.quiz-active {
    padding-top: 0 !important;
    gap: 0 !important;
}
#page-practice.quiz-active > h2 {
    display: none !important;
}
/* Tailwind space-y-4 uses margin-top on siblings, zero it during quiz */
#page-practice.quiz-active > * {
    margin-top: 0 !important;
}
