diff --git a/hyprbars/README.md b/hyprbars/README.md
index 89abc21..7c7d4c4 100644
--- a/hyprbars/README.md
+++ b/hyprbars/README.md
@@ -58,4 +58,6 @@ hyprbars-button = color, size, icon, on-click
 
 Hyprbars supports the following _dynamic_ window rules:
 
-`plugin:hyprbars:nobar` -> disables the bar on matching windows.
\ No newline at end of file
+`plugin:hyprbars:nobar` -> disables the bar on matching windows.
+`plugin:hyprbars:bar_color` -> sets the bar background color on matching windows.
+`plugin:hyprbars:title_color` -> sets the bar title color on matching windows.
diff --git a/hyprbars/barDeco.cpp b/hyprbars/barDeco.cpp
index 7de61a4..0cc7514 100644
--- a/hyprbars/barDeco.cpp
+++ b/hyprbars/barDeco.cpp
@@ -18,7 +18,7 @@ CHyprBar::CHyprBar(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow) {
     m_pMouseMoveCallback =
         HyprlandAPI::registerCallbackDynamic(PHANDLE, "mouseMove", [&](void* self, SCallbackInfo& info, std::any param) { onMouseMove(std::any_cast<Vector2D>(param)); });
 
-    m_pTextTex = makeShared<CTexture>();
+    m_pTextTex    = makeShared<CTexture>();
     m_pButtonsTex = makeShared<CTexture>();
 }
 
@@ -220,7 +220,7 @@ void CHyprBar::renderBarTitle(const Vector2D& bufferSize, const float scale) {
     const auto   scaledButtonsPad  = **PBARBUTTONPADDING * scale;
     const auto   scaledBarPadding  = **PBARPADDING * scale;
 
-    const CColor COLOR = **PCOLOR;
+    const CColor COLOR = m_bForcedTitleColor.value_or(**PCOLOR);
 
     const auto   CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bufferSize.x, bufferSize.y);
     const auto   CAIRO        = cairo_create(CAIROSURFACE);
@@ -412,7 +412,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) {
 
     const auto scaledRounding = ROUNDING > 0 ? ROUNDING * pMonitor->scale - 2 /* idk why but otherwise it looks bad due to the gaps */ : 0;
 
-    CColor     color = **PCOLOR;
+    CColor     color = m_bForcedBarColor.value_or(**PCOLOR);
     color.a *= a;
 
     m_seExtents = {{0, **PHEIGHT}, {}};
@@ -461,7 +461,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) {
     g_pHyprOpenGL->renderRect(&titleBarBox, color, scaledRounding);
 
     // render title
-    if (**PENABLETITLE && (m_szLastTitle != PWINDOW->m_szTitle || m_bWindowSizeChanged || m_pTextTex->m_iTexID == 0)) {
+    if (**PENABLETITLE && (m_szLastTitle != PWINDOW->m_szTitle || m_bWindowSizeChanged || m_pTextTex->m_iTexID == 0 || m_bTitleColorChanged)) {
         m_szLastTitle = PWINDOW->m_szTitle;
         renderBarTitle(BARBUF, pMonitor->scale);
     }
@@ -491,6 +491,7 @@ void CHyprBar::draw(CMonitor* pMonitor, float a) {
     renderBarButtonsText(&textBox, pMonitor->scale, a);
 
     m_bWindowSizeChanged = false;
+    m_bTitleColorChanged = false;
 
     // dynamic updates change the extents
     if (m_iLastHeight != **PHEIGHT) {
@@ -540,11 +541,33 @@ PHLWINDOW CHyprBar::getOwner() {
     return m_pWindow.lock();
 }
 
-void CHyprBar::setHidden(bool hidden) {
-    if (m_bHidden == hidden)
-        return;
+void CHyprBar::updateRules() {
+    const auto PWINDOW                  = m_pWindow.lock();
+    auto       rules                    = PWINDOW->m_vMatchedRules;
+    auto       prev_m_bHidden           = m_bHidden;
+    auto       prev_m_bForcedTitleColor = m_bForcedTitleColor;
 
-    m_bHidden = hidden;
+    m_bForcedBarColor   = std::nullopt;
+    m_bForcedTitleColor = std::nullopt;
+    m_bHidden           = false;
 
-    g_pDecorationPositioner->repositionDeco(this);
+    for (auto& r : rules) {
+        applyRule(r);
+    }
+
+    if (prev_m_bHidden != m_bHidden)
+        g_pDecorationPositioner->repositionDeco(this);
+    if (prev_m_bForcedTitleColor != m_bForcedTitleColor)
+        m_bTitleColorChanged = true;
+}
+
+void CHyprBar::applyRule(const SWindowRule& r) {
+    auto arg = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
+
+    if (r.szRule == "plugin:hyprbars:nobar")
+        m_bHidden = true;
+    else if (r.szRule.starts_with("plugin:hyprbars:bar_color"))
+        m_bForcedBarColor = CColor(configStringToInt(arg));
+    else if (r.szRule.starts_with("plugin:hyprbars:title_color"))
+        m_bForcedTitleColor = CColor(configStringToInt(arg));
 }
diff --git a/hyprbars/barDeco.hpp b/hyprbars/barDeco.hpp
index 0c4fb12..c75d0ec 100644
--- a/hyprbars/barDeco.hpp
+++ b/hyprbars/barDeco.hpp
@@ -34,39 +34,43 @@ class CHyprBar : public IHyprWindowDecoration {
 
     PHLWINDOW                          getOwner();
 
-    void                               setHidden(bool hidden);
+    void                               updateRules();
+    void                               applyRule(const SWindowRule&);
 
   private:
-    SBoxExtents          m_seExtents;
+    SBoxExtents           m_seExtents;
 
-    PHLWINDOWREF         m_pWindow;
+    PHLWINDOWREF          m_pWindow;
 
-    CBox                 m_bAssignedBox;
+    CBox                  m_bAssignedBox;
 
-    SP<CTexture>         m_pTextTex;
-    SP<CTexture>         m_pButtonsTex;
+    SP<CTexture>          m_pTextTex;
+    SP<CTexture>          m_pButtonsTex;
 
-    bool                 m_bWindowSizeChanged = false;
-    bool                 m_bHidden            = false;
+    bool                  m_bWindowSizeChanged = false;
+    bool                  m_bHidden            = false;
+    bool                  m_bTitleColorChanged = false;
+    std::optional<CColor> m_bForcedBarColor;
+    std::optional<CColor> m_bForcedTitleColor;
 
-    Vector2D             cursorRelativeToBar();
+    Vector2D              cursorRelativeToBar();
 
-    void                 renderBarTitle(const Vector2D& bufferSize, const float scale);
-    void                 renderText(SP<CTexture> out, const std::string& text, const CColor& color, const Vector2D& bufferSize, const float scale, const int fontSize);
-    void                 renderBarButtons(const Vector2D& bufferSize, const float scale);
-    void                 renderBarButtonsText(CBox* barBox, const float scale, const float a);
-    void                 onMouseDown(SCallbackInfo& info, IPointer::SButtonEvent e);
-    void                 onMouseMove(Vector2D coords);
-    CBox                 assignedBoxGlobal();
+    void                  renderBarTitle(const Vector2D& bufferSize, const float scale);
+    void                  renderText(SP<CTexture> out, const std::string& text, const CColor& color, const Vector2D& bufferSize, const float scale, const int fontSize);
+    void                  renderBarButtons(const Vector2D& bufferSize, const float scale);
+    void                  renderBarButtonsText(CBox* barBox, const float scale, const float a);
+    void                  onMouseDown(SCallbackInfo& info, IPointer::SButtonEvent e);
+    void                  onMouseMove(Vector2D coords);
+    CBox                  assignedBoxGlobal();
 
-    SP<HOOK_CALLBACK_FN> m_pMouseButtonCallback;
-    SP<HOOK_CALLBACK_FN> m_pMouseMoveCallback;
+    SP<HOOK_CALLBACK_FN>  m_pMouseButtonCallback;
+    SP<HOOK_CALLBACK_FN>  m_pMouseMoveCallback;
 
-    std::string          m_szLastTitle;
+    std::string           m_szLastTitle;
 
-    bool                 m_bDraggingThis  = false;
-    bool                 m_bDragPending   = false;
-    bool                 m_bCancelledDown = false;
+    bool                  m_bDraggingThis  = false;
+    bool                  m_bDragPending   = false;
+    bool                  m_bCancelledDown = false;
 
     // for dynamic updates
     int m_iLastHeight = 0;
diff --git a/hyprbars/main.cpp b/hyprbars/main.cpp
index 060f1a5..7d58476 100644
--- a/hyprbars/main.cpp
+++ b/hyprbars/main.cpp
@@ -49,9 +49,8 @@ static void onUpdateWindowRules(PHLWINDOW window) {
     if (BARIT == g_pGlobalState->bars.end())
         return;
 
-    const auto HASNOBAR = std::find_if(window->m_vMatchedRules.begin(), window->m_vMatchedRules.end(), [](const auto& rule) { return rule.szRule == "plugin:hyprbars:nobar"; }) != window->m_vMatchedRules.end();
-
-    (*BARIT)->setHidden(HASNOBAR);
+    (*BARIT)->updateRules();
+    window->updateWindowDecos();
 }
 
 Hyprlang::CParseResult onNewButton(const char* K, const char* V) {