diff --git a/app/views/accounts/index.html.erb b/app/views/accounts/index.html.erb
index 375d4f65d..86e726e4c 100644
--- a/app/views/accounts/index.html.erb
+++ b/app/views/accounts/index.html.erb
@@ -1,25 +1,21 @@
-
- <%= t(".accounts") %>
-
-
- <%= icon(
- "refresh-cw",
- as_button: true,
- size: "sm",
- href: sync_all_accounts_path,
- disabled: Current.family.syncing?,
- frame: :_top
- ) %>
- <%= render DS::Link.new(
- text: "New account",
- href: new_account_path(return_to: accounts_path),
- variant: "primary",
- icon: "plus",
- frame: :modal
+<%= content_for :page_title, t(".accounts") %>
+<%= content_for :page_actions do %>
+ <%= icon(
+ "refresh-cw",
+ as_button: true,
+ size: "sm",
+ href: sync_all_accounts_path,
+ disabled: Current.family.syncing?,
+ frame: :_top
) %>
-
-
-
+ <%= render DS::Link.new(
+ text: "New account",
+ href: new_account_path(return_to: accounts_path),
+ variant: "primary",
+ icon: "plus",
+ frame: :modal
+ ) %>
+<% end %>
<% if @manual_accounts.empty? && @plaid_items.empty? && @simplefin_items.empty? && @lunchflow_items.empty? && @enable_banking_items.empty? && @coinstats_items.empty? && @coinbase_items.empty? && @mercury_items.empty? && @snaptrade_items.empty? && @indexa_capital_items.empty? %>
<%= render "empty" %>
diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb
index 0c873915b..c9c094396 100644
--- a/app/views/categories/index.html.erb
+++ b/app/views/categories/index.html.erb
@@ -1,26 +1,23 @@
-
- <%= t(".categories") %>
+<%= content_for :page_title, t(".categories") %>
+<%= content_for :page_actions do %>
+ <%= render DS::Menu.new do |menu| %>
+ <% menu.with_item(
+ variant: "button",
+ text: "Delete all",
+ href: destroy_all_categories_path,
+ method: :delete,
+ icon: "trash-2",
+ confirm: CustomConfirm.for_resource_deletion("all categories", high_severity: true)) %>
+ <% end %>
-
- <%= render DS::Menu.new do |menu| %>
- <% menu.with_item(
- variant: "button",
- text: "Delete all",
- href: destroy_all_categories_path,
- method: :delete,
- icon: "trash-2",
- confirm: CustomConfirm.for_resource_deletion("all categories", high_severity: true)) %>
- <% end %>
-
- <%= render DS::Link.new(
- text: t(".new"),
- variant: "primary",
- icon: "plus",
- href: new_category_path,
- frame: :modal
- ) %>
-
-
+ <%= render DS::Link.new(
+ text: t(".new"),
+ variant: "primary",
+ icon: "plus",
+ href: new_category_path,
+ frame: :modal
+ ) %>
+<% end %>
<% if @categories.any? %>
diff --git a/app/views/family_exports/index.html.erb b/app/views/family_exports/index.html.erb
index 906bfa6e3..9299b4131 100644
--- a/app/views/family_exports/index.html.erb
+++ b/app/views/family_exports/index.html.erb
@@ -1,3 +1,5 @@
+<%= content_for :page_title, t(".title") %>
+
<%= settings_section title: t(".title") do %>
<% has_processing = @exports.any? { |e| e.pending? || e.processing? } %>
diff --git a/app/views/family_merchants/index.html.erb b/app/views/family_merchants/index.html.erb
index 0550739ef..648c8b39c 100644
--- a/app/views/family_merchants/index.html.erb
+++ b/app/views/family_merchants/index.html.erb
@@ -1,21 +1,18 @@
-
- <%= t(".title") %>
-
-
- <%= render DS::Link.new(
- text: t(".merge"),
- variant: "outline",
- href: merge_family_merchants_path,
- frame: :modal
- ) %>
- <%= render DS::Link.new(
- text: t(".new"),
- variant: "primary",
- href: new_family_merchant_path,
- frame: :modal
- ) %>
-
-
+<%= content_for :page_title, t(".title") %>
+<%= content_for :page_actions do %>
+ <%= render DS::Link.new(
+ text: t(".merge"),
+ variant: "outline",
+ href: merge_family_merchants_path,
+ frame: :modal
+ ) %>
+ <%= render DS::Link.new(
+ text: t(".new"),
+ variant: "primary",
+ href: new_family_merchant_path,
+ frame: :modal
+ ) %>
+<% end %>
diff --git a/app/views/imports/index.html.erb b/app/views/imports/index.html.erb
index 4a3d9bcda..6f18c0406 100644
--- a/app/views/imports/index.html.erb
+++ b/app/views/imports/index.html.erb
@@ -1,3 +1,5 @@
+<%= content_for :page_title, t(".title") %>
+
<%= settings_section title: t(".title") do %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 6acbcf0bb..8a3baa6c7 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -125,9 +125,9 @@ end %>
<% end %>
<%# SHARED - Main content %>
- <%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 py-4 w-full mx-auto max-w-5xl"), data: { app_layout_target: "content" } do %>
+ <%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 pt-0 pb-4 w-full mx-auto max-w-5xl"), data: { app_layout_target: "content" } do %>
<% unless intro_mode %>
-
+
<%= icon("panel-left", as_button: true, data: { action: "app-layout#toggleLeftSidebar" }) %>
diff --git a/app/views/layouts/settings.html.erb b/app/views/layouts/settings.html.erb
index cf1066a03..41b0734d7 100644
--- a/app/views/layouts/settings.html.erb
+++ b/app/views/layouts/settings.html.erb
@@ -6,25 +6,37 @@
-
diff --git a/app/views/recurring_transactions/index.html.erb b/app/views/recurring_transactions/index.html.erb
index 9ee706fdc..06374fef6 100644
--- a/app/views/recurring_transactions/index.html.erb
+++ b/app/views/recurring_transactions/index.html.erb
@@ -1,28 +1,26 @@
+<%= content_for :page_title, t("recurring_transactions.title") %>
+<%= content_for :page_actions do %>
+ <% unless @family.recurring_transactions_disabled? %>
+ <%= render DS::Menu.new do |menu| %>
+ <% menu.with_item(
+ variant: "button",
+ text: t("recurring_transactions.cleanup_stale"),
+ href: cleanup_recurring_transactions_path,
+ method: :post,
+ icon: "trash-2") %>
+ <% end %>
+
+ <%= render DS::Link.new(
+ text: t("recurring_transactions.identify_patterns"),
+ icon: "search",
+ variant: "outline",
+ href: identify_recurring_transactions_path,
+ method: :post
+ ) %>
+ <% end %>
+<% end %>
+
-
- <%= t("recurring_transactions.title") %>
-
- <% unless @family.recurring_transactions_disabled? %>
- <%= render DS::Menu.new do |menu| %>
- <% menu.with_item(
- variant: "button",
- text: t("recurring_transactions.cleanup_stale"),
- href: cleanup_recurring_transactions_path,
- method: :post,
- icon: "trash-2") %>
- <% end %>
-
- <%= render DS::Link.new(
- text: t("recurring_transactions.identify_patterns"),
- icon: "search",
- variant: "outline",
- href: identify_recurring_transactions_path,
- method: :post
- ) %>
- <% end %>
-
-
-
diff --git a/app/views/rules/index.html.erb b/app/views/rules/index.html.erb
index 2b5867bd5..49282af42 100644
--- a/app/views/rules/index.html.erb
+++ b/app/views/rules/index.html.erb
@@ -1,44 +1,43 @@
-
- Rules
-
- <% if @rules.any? %>
- <%= render DS::Menu.new do |menu| %>
- <% menu.with_item(
- variant: "button",
- text: t("rules.clear_ai_cache.button"),
- href: clear_ai_cache_rules_path,
- icon: "refresh-cw",
- method: :post,
- confirm: CustomConfirm.new(
- title: t("rules.clear_ai_cache.confirm_title"),
- body: t("rules.clear_ai_cache.confirm_body"),
- btn_text: t("rules.clear_ai_cache.confirm_button")
- )) %>
- <% menu.with_item(
- variant: "button",
- text: "Delete all rules",
- href: destroy_all_rules_path,
- icon: "trash-2",
- method: :delete,
- confirm: CustomConfirm.for_resource_deletion("all rules", high_severity: true)) %>
- <% end %>
- <%= render DS::Link.new(
- text: t("rules.apply_all.button"),
- variant: "secondary",
- href: confirm_all_rules_path,
- icon: "play",
- frame: :modal
- ) %>
+<%= content_for :page_title, "Rules" %>
+<%= content_for :page_actions do %>
+ <% if @rules.any? %>
+ <%= render DS::Menu.new do |menu| %>
+ <% menu.with_item(
+ variant: "button",
+ text: t("rules.clear_ai_cache.button"),
+ href: clear_ai_cache_rules_path,
+ icon: "refresh-cw",
+ method: :post,
+ confirm: CustomConfirm.new(
+ title: t("rules.clear_ai_cache.confirm_title"),
+ body: t("rules.clear_ai_cache.confirm_body"),
+ btn_text: t("rules.clear_ai_cache.confirm_button")
+ )) %>
+ <% menu.with_item(
+ variant: "button",
+ text: "Delete all rules",
+ href: destroy_all_rules_path,
+ icon: "trash-2",
+ method: :delete,
+ confirm: CustomConfirm.for_resource_deletion("all rules", high_severity: true)) %>
<% end %>
<%= render DS::Link.new(
- text: "New rule",
- variant: "primary",
- href: new_rule_path(resource_type: "transaction"),
- icon: "plus",
+ text: t("rules.apply_all.button"),
+ variant: "secondary",
+ href: confirm_all_rules_path,
+ icon: "play",
frame: :modal
) %>
-
-
+ <% end %>
+ <%= render DS::Link.new(
+ text: "New rule",
+ variant: "primary",
+ href: new_rule_path(resource_type: "transaction"),
+ icon: "plus",
+ frame: :modal
+ ) %>
+<% end %>
+
<% if self_hosted? %>
<%= icon("circle-alert", size: "sm") %>
diff --git a/app/views/settings/api_keys/show.html.erb b/app/views/settings/api_keys/show.html.erb
index abddad549..91e1bd322 100644
--- a/app/views/settings/api_keys/show.html.erb
+++ b/app/views/settings/api_keys/show.html.erb
@@ -1,7 +1,5 @@
<% if @newly_created && @plain_key %>
-
- API Key Created Successfully
-
+ <%= content_for :page_title, "API Key Created Successfully" %>
<% elsif @current_api_key %>
-
- Your API Key
+ <%= content_for :page_title, "Your API Key" %>
+ <%= content_for :page_actions do %>
<%= render DS::Link.new(
text: "Create New Key",
href: new_settings_api_key_path(regenerate: true),
variant: "secondary"
) %>
-
+ <% end %>
<% else %>
-
- <%= t(".no_api_key.title") %>
+ <%= content_for :page_title, t(".no_api_key.title") %>
+ <%= content_for :page_actions do %>
<%= render DS::Link.new(
text: t(".no_api_key.create_api_key"),
href: new_settings_api_key_path,
variant: "primary"
) %>
-
+ <% end %>
diff --git a/app/views/settings/llm_usages/show.html.erb b/app/views/settings/llm_usages/show.html.erb
index 387ebaf56..c2d4660af 100644
--- a/app/views/settings/llm_usages/show.html.erb
+++ b/app/views/settings/llm_usages/show.html.erb
@@ -1,7 +1,8 @@
+<%= content_for :page_title, "LLM Usage & Costs" %>
+
-
LLM Usage & Costs
-
Track your AI usage and estimated costs
+
Track your AI usage and estimated costs
diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb
index 8ab32898c..ade2df392 100644
--- a/app/views/tags/index.html.erb
+++ b/app/views/tags/index.html.erb
@@ -1,7 +1,5 @@
-
- <%= t(".tags") %>
-
-
+<%= content_for :page_title, t(".tags") %>
+<%= content_for :page_actions do %>
<%= render DS::Menu.new do |menu| %>
<% menu.with_item(
variant: "button",
@@ -12,17 +10,14 @@
confirm: CustomConfirm.for_resource_deletion("all tags", high_severity: true)) %>
<% end %>
- <%= render DS::Link.new(
- text: t(".new"),
- variant: "primary",
- href: new_tag_path,
- icon: "plus",
- frame: :modal
- ) %>
-
-
-
-
+ <%= render DS::Link.new(
+ text: t(".new"),
+ variant: "primary",
+ href: new_tag_path,
+ icon: "plus",
+ frame: :modal
+ ) %>
+<% end %>
<% if @tags.any? %>