diff --git a/gui-apps/ignis/files/ignis-grass-sass.patch b/gui-apps/ignis/files/ignis-grass-sass.patch
new file mode 100644
index 0000000..6775aa9
--- /dev/null
+++ b/gui-apps/ignis/files/ignis-grass-sass.patch
@@ -0,0 +1,125 @@
+diff --git a/ignis/app.py b/ignis/app.py
+index fe6ec39..dc63087 100644
+--- a/ignis/app.py
++++ b/ignis/app.py
+@@ -168,7 +168,7 @@ class IgnisApp(Gtk.Application, IgnisGObject):
+ """
+ Apply a CSS/SCSS/SASS style from a path.
+ If ``style_path`` has a ``.sass`` or ``.scss`` extension, it will be automatically compiled.
+- Requires ``dart-sass`` for SASS/SCSS compilation.
++ Requires either ``dart-sass`` or ``grass-sass`` for SASS/SCSS compilation.
+
+ Args:
+ style_path: Path to the .css/.scss/.sass file.
+diff --git a/ignis/exceptions.py b/ignis/exceptions.py
+index f3a2ed5..e803171 100644
+--- a/ignis/exceptions.py
++++ b/ignis/exceptions.py
+@@ -227,7 +227,7 @@ class GstPluginNotFoundError(Exception):
+
+ class SassCompilationError(Exception):
+ """
+- Raised when Dart Sass compilation fails.
++ Raised when the Sass compilation fails.
+ """
+
+ def __init__(self, stderr: str, *args: object) -> None:
+@@ -239,19 +239,19 @@ class SassCompilationError(Exception):
+ """
+ - required, read-only
+
+- The stderr output from Dart Sass.
++ The stderr output from the Sass compiler.
+ """
+ return self._stderr
+
+
+-class DartSassNotFoundError(Exception):
++class SassNotFoundError(Exception):
+ """
+- Raised when Dart Sass is not found.
++ Raised when a compatible Sass compiler is not found.
+ """
+
+ def __init__(self, *args: object) -> None:
+ super().__init__(
+- "Dart Sass not found! To compile SCSS/SASS, install dart-sass", *args
++ "Sass compiler not found! To compile SCSS/SASS, install either dart-sass or grass-sass", *args
+ )
+
+
+diff --git a/ignis/utils/sass.py b/ignis/utils/sass.py
+index 9bd829d..a25fb2e 100644
+--- a/ignis/utils/sass.py
++++ b/ignis/utils/sass.py
+@@ -1,14 +1,31 @@
+ import os
++import shutil
+ import subprocess
+-from ignis.exceptions import SassCompilationError, DartSassNotFoundError
++from ignis.exceptions import SassCompilationError, SassNotFoundError
+
+ TEMP_DIR = "/tmp/ignis"
+ COMPILED_CSS = f"{TEMP_DIR}/compiled.css"
+ os.makedirs(TEMP_DIR, exist_ok=True)
+
++# pick a Sass compiler
++sass_compiler = None
++
++sass_compilers = [
++ "sass", # dart-sass
++ "grass" # grass-sass
++]
++
++for compiler in sass_compilers:
++ sass_compiler = shutil.which(compiler)
++
++ if sass_compiler:
++ break
++
+
+ def compile_file(path: str) -> str:
+- result = subprocess.run(["sass", path, COMPILED_CSS], capture_output=True)
++ assert sass_compiler
++
++ result = subprocess.run([sass_compiler, path, COMPILED_CSS], capture_output=True)
+
+ if result.returncode != 0:
+ raise SassCompilationError(result.stderr.decode())
+@@ -18,8 +35,10 @@ def compile_file(path: str) -> str:
+
+
+ def compile_string(string: str) -> str:
++ assert sass_compiler
++
+ process = subprocess.Popen(
+- ["sass", "--stdin"],
++ [sass_compiler, "--stdin"],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+@@ -35,7 +54,8 @@ def compile_string(string: str) -> str:
+ def sass_compile(path: str | None = None, string: str | None = None) -> str:
+ """
+ Compile a SASS/SCSS file or string.
+- Requires `Dart Sass `_.
++ Requires either `Dart Sass `_
++ or `Grass `_.
+
+ Args:
+ path: The path to the SASS/SCSS file.
+@@ -43,11 +63,11 @@ def sass_compile(path: str | None = None, string: str | None = None) -> str:
+
+ Raises:
+ TypeError: If neither of the arguments is provided.
+- DartSassNotFoundError: If Dart Sass not found.
++ SassNotFoundError: If no Sass compiler is available.
+ SassCompilationError: If an error occurred while compiling SASS/SCSS.
+ """
+- if not os.path.exists("/bin/sass"):
+- raise DartSassNotFoundError()
++ if not sass_compiler:
++ raise SassNotFoundError()
+
+ if string:
+ return compile_string(string)
diff --git a/gui-apps/ignis/files/ignis-gvc-collision.patch b/gui-apps/ignis/files/ignis-gvc-collision.patch
new file mode 100644
index 0000000..d94ed55
--- /dev/null
+++ b/gui-apps/ignis/files/ignis-gvc-collision.patch
@@ -0,0 +1,24 @@
+Rename libgvc to libgnome-volume-control to prevent
+soname collision with graphviz.
+
+diff -ur a/subprojects/gvc/meson.build b/subprojects/gvc/meson.build
+--- a/subprojects/gvc/meson.build 2025-01-22 16:01:29.637007998 +0100
++++ b/subprojects/gvc/meson.build 2025-01-22 16:03:14.217729940 +0100
+@@ -78,7 +78,7 @@
+ endif
+
+ if enable_static
+- libgvc_static = static_library('gvc',
++ libgvc_static = static_library('gnome-volume-control',
+ sources: libgvc_gir_sources + libgvc_no_gir_sources + libgvc_enums,
+ dependencies: libgvc_deps,
+ c_args: c_args
+@@ -90,7 +90,7 @@
+ error('Installing shared library, but pkglibdir is unset!')
+ endif
+
+- libgvc_shared = shared_library('gvc',
++ libgvc_shared = shared_library('gnome-volume-control',
+ sources: libgvc_gir_sources + libgvc_no_gir_sources + libgvc_enums,
+ dependencies: libgvc_deps,
+ c_args: c_args,
diff --git a/gui-apps/ignis/ignis-0.4.ebuild b/gui-apps/ignis/ignis-0.4.ebuild
new file mode 100644
index 0000000..fbfd626
--- /dev/null
+++ b/gui-apps/ignis/ignis-0.4.ebuild
@@ -0,0 +1,65 @@
+# Copyright 2019-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="A modern widget system"
+HOMEPAGE="https://github.com/linkfrg/ignis"
+
+if [[ ${PV} == "9999" ]]; then
+ inherit git-r3
+ EGIT_REPO_URI="https://github.com/linkfrg/ignis"
+else
+ SRC_URI="https://github.com/linkfrg/${PN}/releases/download/v${PV}/${PN}-v${PV}.tar.gz -> ${P}.tar.gz"
+ KEYWORDS="~amd64 ~x86"
+fi
+
+PYTHON_COMPAT=( python3_{12..13} )
+
+inherit meson python-single-r1
+
+LICENSE="GPL-3"
+SLOT="0"
+IUSE="pipewire gstreamer networkmanager upower bluetooth"
+REQUIRED_USE="${PYTHON_REQUIRED_USE}"
+
+COMMON_DEPEND="
+ ${PYTHON_DEPS}
+"
+
+DEPEND="${COMMON_DEPEND}
+ dev-libs/glib:2
+ sys-libs/glibc
+ gui-libs/gtk:4
+ gui-libs/gtk4-layer-shell
+ media-libs/libpulse
+ dev-python/pycairo
+ dev-python/pygobject
+ dev-python/click
+ dev-python/requests
+ dev-python/loguru
+ pipewire? ( media-video/pipewire[gstreamer?] )
+ gstreamer? (
+ media-libs/gst-plugins-good
+ media-libs/gst-plugins-ugly
+ )
+ networkmanager? ( net-misc/networkmanager )
+ upower? ( sys-power/upower )
+ bluetooth? ( net-wireless/gnome-bluetooth )
+"
+
+BDEPEND="${COMMON_DEPEND}
+ sys-devel/gettext
+"
+
+PATCHES=(
+ "${FILESDIR}"/${PN}-gvc-collision.patch
+ "${FILESDIR}"/${PN}-grass-sass.patch
+)
+
+S="${WORKDIR}/${PN}"
+
+src_install() {
+ meson_src_install
+ python_optimize "${D}$(python_get_sitedir)/${PN}"
+}