diff --git a/kotlin/src/kawaii/packetik/sfx/SfxNative.kt b/kotlin/src/kawaii/packetik/sfx/SfxNative.kt
new file mode 100644
index 00000000..49e0248b
--- /dev/null
+++ b/kotlin/src/kawaii/packetik/sfx/SfxNative.kt
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// Native builders for the SFX settings page. Host-only classes (UItem,
+// SlideIntChooseView and Theme) are resolved through reflection so this source
+// still compiles against the public Android SDK.
+
+package kawaii.packetik.sfx
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+import android.util.TypedValue
+import android.view.Gravity
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.SeekBar
+import android.widget.TextView
+import java.lang.reflect.InvocationHandler
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
+import java.lang.reflect.Proxy
+
+object SfxNative {
+
+    private const val UITEM_CLASS = "org.telegram.ui.Components.UItem"
+
+    @JvmStatic
+    fun createExpandable(
+        classLoader: ClassLoader,
+        id: Int,
+        text: String,
+        subtext: String,
+        checked: Boolean,
+        collapsed: Boolean,
+        switchClick: View.OnClickListener?
+    ): Any? {
+        return try {
+            val cls = Class.forName(UITEM_CLASS, true, classLoader)
+            val factory = findStatic(cls, "asExteraExpandableSwitch", 4)
+            val item = factory.invoke(null, id, text, subtext, switchClick) ?: return null
+            call(item, "setChecked", checked)
+            call(item, "setCollapsed", collapsed)
+            item
+        } catch (_: Throwable) {
+            null
+        }
+    }
+
+    @JvmStatic
+    fun createChild(
+        classLoader: ClassLoader,
+        id: Int,
+        text: String,
+        checked: Boolean
+    ): Any? {
+        return try {
+            val cls = Class.forName(UITEM_CLASS, true, classLoader)
+            val factory = findStatic(cls, "asRoundCheckbox", 2)
+            val item = factory.invoke(null, id, text) ?: return null
+            call(item, "setChecked", checked)
+            call(item, "pad")
+            item
+        } catch (_: Throwable) {
+            null
+        }
+    }
+
+    @JvmStatic
+    fun createVolumeSlider(
+        context: Context,
+        initial: Int,
+        title: String,
+        offLabel: String,
+        maximumLabel: String,
+        onChange: InvocationHandler?
+    ): View {
+        return VolumeSlider(
+            context,
+            initial.coerceIn(0, 100),
+            title,
+            offLabel,
+            maximumLabel,
+            onChange
+        )
+    }
+
+    private fun findStatic(cls: Class<*>, name: String, count: Int): Method {
+        return cls.methods.firstOrNull {
+            it.name == name && it.parameterCount == count && Modifier.isStatic(it.modifiers)
+        }?.apply { isAccessible = true }
+            ?: throw NoSuchMethodException("$name/$count on ${cls.name}")
+    }
+
+    private fun findMethod(cls: Class<*>, name: String, count: Int): Method {
+        var current: Class<*>? = cls
+        while (current != null) {
+            current.declaredMethods.firstOrNull {
+                it.name == name && it.parameterCount == count
+            }?.let {
+                it.isAccessible = true
+                return it
+            }
+            current = current.superclass
+        }
+        throw NoSuchMethodException("$name/$count on ${cls.name}")
+    }
+
+    private fun call(target: Any, name: String, vararg args: Any?): Any? {
+        return findMethod(target.javaClass, name, args.size).invoke(target, *args)
+    }
+
+    private fun callbackMarker(value: Int) = value
+
+    private class VolumeSlider(
+        context: Context,
+        initial: Int,
+        private val titleText: String,
+        private val offLabel: String,
+        private val maximumLabel: String,
+        private val onChange: InvocationHandler?
+    ) : LinearLayout(context) {
+
+        private val hostLoader = context.classLoader
+        private val callbackMethod = SfxNative::class.java.getDeclaredMethod(
+            "callbackMarker",
+            Int::class.javaPrimitiveType
+        ).apply { isAccessible = true }
+
+        init {
+            orientation = VERTICAL
+            setBackgroundColor(themeColor("key_windowBackgroundWhite", Color.WHITE))
+            if (!buildMd3(context, initial)) {
+                buildSeekBar(context, initial)
+            }
+        }
+
+        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+            super.onMeasure(
+                MeasureSpec.makeMeasureSpec(
+                    MeasureSpec.getSize(widthMeasureSpec),
+                    MeasureSpec.EXACTLY
+                ),
+                MeasureSpec.makeMeasureSpec(dp(104), MeasureSpec.EXACTLY)
+            )
+        }
+
+        private fun buildMd3(context: Context, initial: Int): Boolean {
+            return try {
+                val slideClass = Class.forName(
+                    "org.telegram.ui.Cells.SlideIntChooseView",
+                    true,
+                    hostLoader
+                )
+                val optionsClass = Class.forName(
+                    "org.telegram.ui.Cells.SlideIntChooseView\$Options",
+                    true,
+                    hostLoader
+                )
+                val utilitiesClass = Class.forName(
+                    "org.telegram.messenger.Utilities",
+                    true,
+                    hostLoader
+                )
+                val plainInterface = Class.forName(
+                    "org.telegram.messenger.Utilities\$CallbackReturn",
+                    true,
+                    hostLoader
+                )
+                val formatInterface = Class.forName(
+                    "org.telegram.messenger.Utilities\$Callback2Return",
+                    true,
+                    hostLoader
+                )
+                val changeInterface = Class.forName(
+                    "org.telegram.messenger.Utilities\$Callback",
+                    true,
+                    hostLoader
+                )
+
+                val plain = Proxy.newProxyInstance(
+                    hostLoader,
+                    arrayOf(plainInterface)
+                ) { _, method, args ->
+                    if (method.name == "run") args?.getOrNull(0)?.toString() ?: ""
+                    else defaultProxyValue(method.returnType)
+                }
+                val make = optionsClass.methods.firstOrNull {
+                    it.name == "make" && it.parameterCount == 4 &&
+                        Modifier.isStatic(it.modifiers)
+                } ?: return false
+                val options = make.invoke(null, 0, 0, 100, plain) ?: return false
+
+                val formatter = Proxy.newProxyInstance(
+                    hostLoader,
+                    arrayOf(formatInterface)
+                ) { _, method, args ->
+                    if (method.name == "run") {
+                        val type = (args?.getOrNull(0) as? Number)?.toInt() ?: 0
+                        val value = (args?.getOrNull(1) as? Number)?.toInt() ?: 0
+                        if (type == 0) volumeLabel(value) else "$value%"
+                    } else {
+                        defaultProxyValue(method.returnType)
+                    }
+                }
+                options.javaClass.getDeclaredField("toString").apply {
+                    isAccessible = true
+                    set(options, formatter)
+                }
+
+                val callback = Proxy.newProxyInstance(
+                    hostLoader,
+                    arrayOf(changeInterface)
+                ) { _, method, args ->
+                    if (method.name == "run") {
+                        notifyChanged((args?.getOrNull(0) as? Number)?.toInt() ?: initial)
+                    }
+                    defaultProxyValue(method.returnType)
+                }
+
+                val ctor = slideClass.declaredConstructors.firstOrNull {
+                    it.parameterCount == 2
+                } ?: slideClass.declaredConstructors.firstOrNull {
+                    it.parameterCount == 1
+                } ?: return false
+                ctor.isAccessible = true
+                val slider = if (ctor.parameterCount == 2) {
+                    ctor.newInstance(context, null)
+                } else {
+                    ctor.newInstance(context)
+                } as? View ?: return false
+
+                val setMethod = slideClass.methods.firstOrNull {
+                    it.name == "set" && it.parameterCount == 3
+                } ?: return false
+                setMethod.invoke(slider, initial, options, callback)
+
+                setPadding(0, dp(6), 0, 0)
+                addView(makeText(titleText, 16f, "key_windowBackgroundWhiteBlackText"),
+                    linearParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 22, 0, 22, 0))
+                addView(slider, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
+                true
+            } catch (_: Throwable) {
+                false
+            }
+        }
+
+        private fun buildSeekBar(context: Context, initial: Int) {
+            setPadding(dp(21), dp(8), dp(21), dp(8))
+            gravity = Gravity.CENTER_VERTICAL
+
+            val row = LinearLayout(context).apply {
+                orientation = HORIZONTAL
+                gravity = Gravity.CENTER_VERTICAL
+            }
+            addView(row, linearParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0, 0, 6))
+
+            row.addView(
+                makeText(titleText, 16f, "key_windowBackgroundWhiteBlackText"),
+                LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
+            )
+            val value = makeText(
+                volumeLabel(initial),
+                14f,
+                "key_windowBackgroundWhiteGrayText"
+            )
+            row.addView(value, LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT))
+
+            val seekBar = SeekBar(context).apply {
+                max = 100
+                progress = initial
+            }
+            try {
+                val accent = themeColor("key_featuredStickers_addButton", Color.BLUE)
+                val filter = PorterDuffColorFilter(accent, PorterDuff.Mode.SRC_IN)
+                seekBar.progressDrawable?.colorFilter = filter
+                seekBar.thumb?.colorFilter = filter
+            } catch (_: Throwable) {
+            }
+            seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+                override fun onProgressChanged(bar: SeekBar?, progress: Int, fromUser: Boolean) {
+                    value.text = volumeLabel(progress)
+                    if (fromUser) notifyChanged(progress)
+                }
+
+                override fun onStartTrackingTouch(bar: SeekBar?) = Unit
+                override fun onStopTrackingTouch(bar: SeekBar?) = Unit
+            })
+            addView(seekBar, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
+        }
+
+        private fun notifyChanged(value: Int) {
+            try {
+                onChange?.invoke(this, callbackMethod, arrayOf(value.coerceIn(0, 100)))
+            } catch (_: Throwable) {
+            }
+        }
+
+        private fun volumeLabel(value: Int): String {
+            return when (value) {
+                0 -> offLabel
+                100 -> maximumLabel
+                else -> "$value%"
+            }
+        }
+
+        private fun makeText(textValue: String, size: Float, colorKey: String): TextView {
+            return TextView(context).apply {
+                text = textValue
+                setTextSize(TypedValue.COMPLEX_UNIT_DIP, size)
+                setTextColor(themeColor(colorKey, Color.DKGRAY))
+                gravity = Gravity.CENTER_VERTICAL
+            }
+        }
+
+        private fun themeColor(keyName: String, fallback: Int): Int {
+            return try {
+                val theme = Class.forName(
+                    "org.telegram.ui.ActionBar.Theme",
+                    true,
+                    hostLoader
+                )
+                val key = theme.getDeclaredField(keyName).apply {
+                    isAccessible = true
+                }.get(null)
+                val method = theme.methods.firstOrNull {
+                    it.name == "getColor" && it.parameterCount == 1 &&
+                        Modifier.isStatic(it.modifiers)
+                } ?: return fallback
+                (method.invoke(null, key) as? Number)?.toInt() ?: fallback
+            } catch (_: Throwable) {
+                fallback
+            }
+        }
+
+        private fun linearParams(
+            width: Int,
+            height: Int,
+            left: Int,
+            top: Int,
+            right: Int,
+            bottom: Int
+        ): LayoutParams {
+            return LayoutParams(width, height).apply {
+                setMargins(dp(left), dp(top), dp(right), dp(bottom))
+            }
+        }
+
+        private fun dp(value: Int): Int {
+            return (value * resources.displayMetrics.density + 0.5f).toInt()
+        }
+
+        private fun defaultProxyValue(type: Class<*>): Any? {
+            if (!type.isPrimitive || type == Void.TYPE) return null
+            return when (type) {
+                java.lang.Boolean.TYPE -> false
+                java.lang.Character.TYPE -> '\u0000'
+                java.lang.Byte.TYPE -> 0.toByte()
+                java.lang.Short.TYPE -> 0.toShort()
+                java.lang.Integer.TYPE -> 0
+                java.lang.Long.TYPE -> 0L
+                java.lang.Float.TYPE -> 0f
+                java.lang.Double.TYPE -> 0.0
+                else -> null
+            }
+        }
+    }
+}
diff --git a/packit/.elyxbuilder/stats.yml b/packit/.elyxbuilder/stats.yml
index 503f8a34..c74ed0b7 100644
--- a/packit/.elyxbuilder/stats.yml
+++ b/packit/.elyxbuilder/stats.yml
@@ -1,4 +1,4 @@
-builds: 547
-compiledBuilds: 12
-failedBuilds: 8
+builds: 549
+compiledBuilds: 13
+failedBuilds: 9
 uncompiledBuilds: 527
diff --git a/packit/dex/sfx.dex b/packit/dex/sfx.dex
new file mode 100644
index 00000000..066fdbab
Binary files /dev/null and b/packit/dex/sfx.dex differ
diff --git a/packit/meta.yml b/packit/meta.yml
index a0f17fd3..d41ef320 100644
--- a/packit/meta.yml
+++ b/packit/meta.yml
@@ -1,7 +1,7 @@
 name: PackIt
 description: "{plugin_description} [shareui/packit-source](https://github.com/shareui/packit-source)"
 id: shareui_packit
-version: "0.0.0-rc.651"
+version: "0.0.0-rc.652"
 author: "@packitX"
 app_version: ">=12.8.1"
 sdk_version: ">=1.4.4.6"
diff --git a/packit/src/SettingsActivity/SubSettings/sfx.py b/packit/src/SettingsActivity/SubSettings/sfx.py
index 6f8e6581..aca2881e 100644
--- a/packit/src/SettingsActivity/SubSettings/sfx.py
+++ b/packit/src/SettingsActivity/SubSettings/sfx.py
@@ -1,27 +1,161 @@
 # pyright: reportMissingImports=false
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from ui.settings import Header, Divider
-from elyx import strings
+from packutil import logx
+from ui.settings import Header, Divider, Custom
+from elyx import strings, settings
+
+_SFX_CHILDREN = [
+    ("sfx_install", "sfx_install", False),
+    ("sfx_copy_link", "sfx_copy_link", False),
+    ("sfx_search", "sfx_search", False),
+    ("sfx_clear_search", "sfx_clear_search", False),
+    ("sfx_achievement", "sfx_achievement", True),
+    ("sfx_available_updates", "sfx_available_updates", False),
+]
+
+
+def _item_id(key):
+    return hash(key) & 0x7FFFFFFF
+
+
+def _reload():
+    settings.set("_es_dummy", not settings.get("_es_dummy", False), reload_settings=True)
+
+
+def _make_expandable(other_settings, ctx):
+    try:
+        from android_utils import OnClickListener
+        from ...dexLoader import sfxExpandableCreate
+
+        checked_count = sum(
+            1 for key, _, default in _SFX_CHILDREN if settings.get(key, default)
+        )
+
+        def switch_click(view):
+            new_value = not any(
+                settings.get(key, default)
+                for key, _, default in _SFX_CHILDREN
+            )
+            for key, _, _ in _SFX_CHILDREN:
+                settings.set(key, new_value, reload_settings=False)
+            _reload()
+
+        listener = OnClickListener(switch_click)
+        item = sfxExpandableCreate(
+            ctx,
+            _item_id("sfx_enabled"),
+            strings.sfx_header,
+            f"{checked_count}/{len(_SFX_CHILDREN)}",
+            checked_count > 0,
+            not other_settings._es_is_expanded("sfx_enabled"),
+            listener,
+        )
+        if item is None:
+            from org.telegram.ui.Components import UItem
+            item = UItem.asExteraExpandableSwitch(
+                _item_id("sfx_enabled"),
+                strings.sfx_header,
+                f"{checked_count}/{len(_SFX_CHILDREN)}",
+                listener,
+            )
+            item.setChecked(checked_count > 0)
+            item.setCollapsed(not other_settings._es_is_expanded("sfx_enabled"))
+        return Custom(
+            item=item,
+            on_click=lambda view: other_settings._es_toggle_and_reload("sfx_enabled"),
+        )
+    except Exception as e:
+        logx(f"sfx: expandable create error: {e}", False)
+        return None
+
+
+def _make_child(ctx, key, text, default):
+    try:
+        from ...dexLoader import sfxChildCreate
+
+        item = sfxChildCreate(
+            ctx,
+            _item_id(key),
+            text,
+            settings.get(key, default),
+        )
+        if item is None:
+            from org.telegram.ui.Components import UItem
+            item = UItem.asRoundCheckbox(_item_id(key), text)
+            item.setChecked(settings.get(key, default))
+            item.pad()
+
+        def on_click(view):
+            settings.set(key, not settings.get(key, default), reload_settings=False)
+            _reload()
+
+        return Custom(item=item, on_click=on_click)
+    except Exception as e:
+        logx(f"sfx: child {key} create error: {e}", False)
+        return None
+
+
+def _make_volume_slider(ctx):
+    try:
+        from java import dynamic_proxy
+        from java.lang.reflect import InvocationHandler
+        from ...dexLoader import sfxVolumeSliderCreate
+
+        class _VolumeChange(dynamic_proxy(InvocationHandler)):
+            def invoke(self, proxy, method, args):
+                if args:
+                    settings.set("sfx_volume", int(args[0]), reload_settings=False)
+                return None
+
+        initial = int(settings.get("sfx_volume", 100))
+        off_label = strings["sfx_volume_off"]
+        maximum_label = strings["sfx_volume_maximum"]
+        view = sfxVolumeSliderCreate(
+            ctx,
+            initial,
+            strings.sfx_volume,
+            off_label,
+            maximum_label,
+            _VolumeChange(),
+        )
+        if view is None:
+            from ...ui.md3Slider import createMd3Slider
+
+            def on_change(value):
+                settings.set("sfx_volume", int(value), reload_settings=False)
+
+            def format_value(label_type, value):
+                if label_type != 0:
+                    return f"{value}%"
+                if value == 0:
+                    return off_label
+                if value == 100:
+                    return maximum_label
+                return f"{value}%"
+
+            slider = createMd3Slider(
+                ctx, 0, 100, initial, on_change, format_value
+            )
+            view = slider.view if slider is not None else None
+        return Custom(view=view) if view is not None else None
+    except Exception as e:
+        logx(f"sfx: volume slider create error: {e}", False)
+        return None
 
 def build_sfx_page(other_settings, ctx):
+    expanded = other_settings._es_is_expanded("sfx_enabled")
     items = [
         Header(text=strings.sfx_header),
-        other_settings._make_expandable_switch("sfx_enabled", strings.sfx_header, [
-            ("sfx_install", False),
-            ("sfx_copy_link", False),
-            ("sfx_search", False),
-            ("sfx_clear_search", False),
-            ("sfx_achievement", True),
-            ("sfx_available_updates", False),
-        ]),
-        other_settings._make_es_child("sfx_install", strings.sfx_install, False) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._make_es_child("sfx_copy_link", strings.sfx_copy_link, False) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._make_es_child("sfx_search", strings.sfx_search, False) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._make_es_child("sfx_clear_search", strings.sfx_clear_search, False) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._make_es_child("sfx_achievement", strings.sfx_achievement, True) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._make_es_child("sfx_available_updates", strings.sfx_available_updates, False) if other_settings._es_is_expanded("sfx_enabled") else None,
-        other_settings._build_sfx_volume_slider(ctx),
+        _make_expandable(other_settings, ctx),
+        *(
+            [
+                _make_child(ctx, key, getattr(strings, label), default)
+                for key, label, default in _SFX_CHILDREN
+            ]
+            if expanded else []
+        ),
+        _make_volume_slider(ctx),
         Divider(text=strings.sfx_header_desc),
     ]
-    return [item for item in items if item is not None]
\ No newline at end of file
+    return [item for item in items if item is not None]
diff --git a/packit/src/SettingsActivity/service/fastExpandableHook.py b/packit/src/SettingsActivity/service/fastExpandableHook.py
index e023ce1d..5af0787c 100644
--- a/packit/src/SettingsActivity/service/fastExpandableHook.py
+++ b/packit/src/SettingsActivity/service/fastExpandableHook.py
@@ -16,6 +16,7 @@
         ("sfx_search", False),
         ("sfx_clear_search", False),
         ("sfx_achievement", True),
+        ("sfx_available_updates", False),
     ],
     "inline_send_enabled": [
         ("inline_send_name", True),
@@ -159,4 +160,4 @@ def _original_call(param):
         return param.method.invoke(param.thisObject, param.args)
     except Exception as e:
         logx(f"fastExpandableHook: _original_call error: {e}", False)
-        return None
\ No newline at end of file
+        return None
diff --git a/packit/src/SettingsActivity/settings.py b/packit/src/SettingsActivity/settings.py
index 4e82dc4f..c4c8093c 100644
--- a/packit/src/SettingsActivity/settings.py
+++ b/packit/src/SettingsActivity/settings.py
@@ -44,7 +44,7 @@
 from dataclasses import dataclass, field
 from ..ui.FontPickerBottomSheet import showFontPicker
 from ..ui.FontManager import getSelectedFilename
-from extera_utils.classes import Base, java_subclass, jMVELoverride, joverride
+from extera_utils.classes import Base, java_subclass, joverride
 
 def _reload_plugin_settings():
     try:
@@ -1311,151 +1311,6 @@ def _buildSortMenuDesignToggle(context, key, default, on_change=None):
         return None
 
 
-@java_subclass(LinearLayout)
-class SfxVolumeSlider(Base):
-    # tall enough for the title row + the 75dp MD3 SlideIntChooseView; the
-    # SeekBar fallback centers itself vertically in the same height
-    onMeasure = jMVELoverride(
-        arguments=[("widthMeasureSpec", "int"), ("heightMeasureSpec", "int")],
-        code="""
-            SUPER_onMeasure(
-                android.view.View$MeasureSpec.makeMeasureSpec(
-                    android.view.View$MeasureSpec.getSize(widthMeasureSpec),
-                    android.view.View$MeasureSpec.EXACTLY
-                ),
-                android.view.View$MeasureSpec.makeMeasureSpec(
-                    org.telegram.messenger.AndroidUtilities.dp(104),
-                    android.view.View$MeasureSpec.EXACTLY
-                )
-            );
-            return null;
-        """,
-    )
-
-    def on_post_init(self, context):
-        from android.view import Gravity
-        from elyx import settings as _s
-        dp = AndroidUtilities.dp
-
-        self._s = _s
-        self._md3 = None
-        self.setOrientation(LinearLayout.VERTICAL)
-        self.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite))
-
-        try:
-            initial = int(_s.get("sfx_volume", 100))
-        except Exception:
-            initial = 100
-
-        def _on_change(v):
-            try:
-                _s.set("sfx_volume", int(v), reload_settings=False)
-            except Exception:
-                pass
-
-        def _fmt(label_type, v):
-            # center label shows the pretty value, edges show plain percents
-            if label_type == 0:
-                return SfxVolumeSlider._volLabel(v)
-            return f"{v}%"
-
-        try:
-            from ..ui.md3Slider import createMd3Slider
-            md3 = createMd3Slider(context, 0, 100, initial, _on_change, _fmt)
-        except Exception as e:
-            logx(f"SfxVolumeSlider: md3 import/create error: {e}", False)
-            md3 = None
-
-        if md3 is not None:
-            self.setPadding(0, dp(6), 0, 0)
-            title = TextView(context)
-            title.setText(str(strings.sfx_volume))
-            title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16)
-            title.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText))
-            self.addView(title, LayoutHelper.createLinear(-2, -2, 22, 0, 22, 0))
-            # the MD3 cell is edge-to-edge with its own 22dp text insets
-            self.addView(md3.view, LayoutHelper.createLinear(-1, -2))
-            self._md3 = md3
-            return
-
-        self._build_seekbar_fallback(context)
-
-    def _build_seekbar_fallback(self, context):
-        from android.widget import SeekBar
-        from android.view import Gravity
-        from java import dynamic_proxy
-        _s = self._s
-        dp = AndroidUtilities.dp
-
-        self.setPadding(dp(21), dp(8), dp(21), dp(8))
-        self.setGravity(Gravity.CENTER_VERTICAL)
-
-        labelRow = LinearLayout(context)
-        labelRow.setOrientation(LinearLayout.HORIZONTAL)
-        labelRow.setGravity(Gravity.CENTER_VERTICAL)
-        self.addView(labelRow, LayoutHelper.createLinear(-1, -2, 0, 0, 0, 6))
-
-        self._labelView = TextView(context)
-        self._labelView.setText(str(strings.sfx_volume))
-        self._labelView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16)
-        self._labelView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText))
-        labelRow.addView(self._labelView, LayoutHelper.createLinear(0, -2, 1.0, Gravity.CENTER_VERTICAL))
-
-        self._valueView = TextView(context)
-        self._valueView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14)
-        self._valueView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText))
-        labelRow.addView(self._valueView, LayoutHelper.createLinear(-2, -2, Gravity.CENTER_VERTICAL))
-
-        self._seekBar = SeekBar(context)
-        self._seekBar.setMax(100)
-
-        try:
-            from android.graphics import PorterDuff, PorterDuffColorFilter
-            accent = Theme.getColor(Theme.key_featuredStickers_addButton)
-            self._seekBar.getProgressDrawable().setColorFilter(PorterDuffColorFilter(accent, PorterDuff.Mode.SRC_IN))
-            self._seekBar.getThumb().setColorFilter(PorterDuffColorFilter(accent, PorterDuff.Mode.SRC_IN))
-        except Exception:
-            pass
-
-        valueView = self._valueView
-
-        class _ChangeListener(dynamic_proxy(SeekBar.OnSeekBarChangeListener)):
-            def onProgressChanged(self_l, sb, progress, fromUser):
-                try:
-                    _s.set("sfx_volume", progress, reload_settings=False)
-                    valueView.setText(SfxVolumeSlider._volLabel(progress))
-                except Exception:
-                    pass
-
-            def onStartTrackingTouch(self_l, sb):
-                pass
-
-            def onStopTrackingTouch(self_l, sb):
-                pass
-
-        self._seekBar.setOnSeekBarChangeListener(_ChangeListener())
-        self.addView(self._seekBar, LayoutHelper.createLinear(-1, -2))
-
-    def bind(self):
-        try:
-            vol = int(self._s.get("sfx_volume", 100))
-        except Exception:
-            vol = 100
-        if self._md3 is not None:
-            self._md3.set_value(vol, False)
-            return
-        self._seekBar.setProgress(vol)
-        self._valueView.setText(SfxVolumeSlider._volLabel(vol))
-
-    @staticmethod
-    def _volLabel(v):
-        if v == 0:
-            return str(strings["sfx_volume_off"])
-        if v == 100:
-            return str(strings["sfx_volume_maximum"])
-        return f"{v}%"
-
-
 class OtherSettings:
     def __init__(self, chat_button=None, plugin=None):
         self.chat_button = chat_button
@@ -1622,19 +1477,6 @@ def _build_hash_function_item(self, ctx):
             icon="msg_sendfile",
         )
 
-    def _build_sfx_volume_slider(self, ctx):
-        # slider 0-100 for sfx_volume setting, shown as a separate row under sfx section
-        try:
-            if not ctx:
-                return None
-            slider = SfxVolumeSlider.new_instance(ctx)
-            slider.bind()
-            return Custom(view=slider.java)
-        except Exception as e:
-            logx(f"other: _build_sfx_volume_slider error: {e}", False)
-            return None
-
-
     def _open_main_menu_settings(self, view):
         try:
             from hook_utils import find_class
@@ -2137,4 +1979,4 @@ def build(self):
             link_alias="file_settings"
         ))
 
-        return items
\ No newline at end of file
+        return items
diff --git a/packit/src/dexLoader.py b/packit/src/dexLoader.py
index fc43efe9..2c8f33ca 100644
--- a/packit/src/dexLoader.py
+++ b/packit/src/dexLoader.py
@@ -139,6 +139,7 @@ def _ia(lst):
 
 
 _CATALOG_CLASS = "kawaii.packetik.catalog.CatalogChromeNative"
+_SFX_CLASS = "kawaii.packetik.sfx.SfxNative"
 
 
 def catalogChromeCreate(context, main_bg, card_bg, card_pressed, text_color,
@@ -203,6 +204,64 @@ def _i(v):
         return None
 
 
+def sfxExpandableCreate(context, item_id, text, subtext, checked, collapsed,
+                        switch_click):
+    try:
+        if context is None:
+            from org.telegram.messenger import ApplicationLoader
+            context = ApplicationLoader.applicationContext
+        cls = _loadClass("sfx", _SFX_CLASS, context)
+        if cls is None:
+            return None
+        from java import jint
+        return _callStatic(
+            cls, "createExpandable",
+            context.getClassLoader(), jint(int(item_id)), str(text), str(subtext),
+            bool(checked), bool(collapsed), switch_click,
+        )
+    except Exception as e:
+        logx(f"dexLoader: sfxExpandableCreate error: {e}", False)
+        return None
+
+
+def sfxChildCreate(context, item_id, text, checked):
+    try:
+        if context is None:
+            from org.telegram.messenger import ApplicationLoader
+            context = ApplicationLoader.applicationContext
+        cls = _loadClass("sfx", _SFX_CLASS, context)
+        if cls is None:
+            return None
+        from java import jint
+        return _callStatic(
+            cls, "createChild",
+            context.getClassLoader(), jint(int(item_id)), str(text), bool(checked),
+        )
+    except Exception as e:
+        logx(f"dexLoader: sfxChildCreate error: {e}", False)
+        return None
+
+
+def sfxVolumeSliderCreate(context, initial, title, off_label, maximum_label,
+                          on_change):
+    try:
+        if context is None:
+            from org.telegram.messenger import ApplicationLoader
+            context = ApplicationLoader.applicationContext
+        cls = _loadClass("sfx", _SFX_CLASS, context)
+        if cls is None:
+            return None
+        from java import jint
+        return _callStatic(
+            cls, "createVolumeSlider",
+            context, jint(int(initial)), str(title), str(off_label),
+            str(maximum_label), on_change,
+        )
+    except Exception as e:
+        logx(f"dexLoader: sfxVolumeSliderCreate error: {e}", False)
+        return None
+
+
 def openFileCancel(view):
     try:
         cls = _loaded.get("openfile")
diff --git a/scripts/linux/kotlin-build.sh b/scripts/linux/kotlin-build.sh
index 57cd99b2..dc12d571 100644
--- a/scripts/linux/kotlin-build.sh
+++ b/scripts/linux/kotlin-build.sh
@@ -26,6 +26,7 @@ PACKAGES=(
   "badges=kawaii.packetik.badges.BadgesNative"
   "openfile=kawaii.packetik.openfile.OpenFileNative"
   "catalog=kawaii.packetik.catalog.CatalogChromeNative"
+  "sfx=kawaii.packetik.sfx.SfxNative"
 )
 
 die() { echo "error: $*" >&2; exit 1; }
