diff --git a/Telegram/Resources/icons/menu/chat_bubble.png b/Telegram/Resources/icons/menu/chat_bubble.png
new file mode 100644
index 000000000..a22bd585d
Binary files /dev/null and b/Telegram/Resources/icons/menu/chat_bubble.png differ
diff --git a/Telegram/Resources/icons/menu/chat_bubble@2x.png b/Telegram/Resources/icons/menu/chat_bubble@2x.png
new file mode 100644
index 000000000..8da64703f
Binary files /dev/null and b/Telegram/Resources/icons/menu/chat_bubble@2x.png differ
diff --git a/Telegram/Resources/icons/menu/chat_bubble@3x.png b/Telegram/Resources/icons/menu/chat_bubble@3x.png
new file mode 100644
index 000000000..5862e9228
Binary files /dev/null and b/Telegram/Resources/icons/menu/chat_bubble@3x.png differ
diff --git a/Telegram/Resources/icons/menu/emoji.png b/Telegram/Resources/icons/menu/emoji.png
new file mode 100644
index 000000000..0820c4c24
Binary files /dev/null and b/Telegram/Resources/icons/menu/emoji.png differ
diff --git a/Telegram/Resources/icons/menu/emoji@2x.png b/Telegram/Resources/icons/menu/emoji@2x.png
new file mode 100644
index 000000000..24ced3250
Binary files /dev/null and b/Telegram/Resources/icons/menu/emoji@2x.png differ
diff --git a/Telegram/Resources/icons/menu/emoji@3x.png b/Telegram/Resources/icons/menu/emoji@3x.png
new file mode 100644
index 000000000..d2251e543
Binary files /dev/null and b/Telegram/Resources/icons/menu/emoji@3x.png differ
diff --git a/Telegram/Resources/icons/menu/phone.png b/Telegram/Resources/icons/menu/phone.png
new file mode 100644
index 000000000..d059c8e9a
Binary files /dev/null and b/Telegram/Resources/icons/menu/phone.png differ
diff --git a/Telegram/Resources/icons/menu/phone@2x.png b/Telegram/Resources/icons/menu/phone@2x.png
new file mode 100644
index 000000000..920fc33b4
Binary files /dev/null and b/Telegram/Resources/icons/menu/phone@2x.png differ
diff --git a/Telegram/Resources/icons/menu/phone@3x.png b/Telegram/Resources/icons/menu/phone@3x.png
new file mode 100644
index 000000000..853e7e11a
Binary files /dev/null and b/Telegram/Resources/icons/menu/phone@3x.png differ
diff --git a/Telegram/Resources/icons/settings/battery.png b/Telegram/Resources/icons/settings/battery.png
new file mode 100644
index 000000000..4287599be
Binary files /dev/null and b/Telegram/Resources/icons/settings/battery.png differ
diff --git a/Telegram/Resources/icons/settings/battery@2x.png b/Telegram/Resources/icons/settings/battery@2x.png
new file mode 100644
index 000000000..b45409949
Binary files /dev/null and b/Telegram/Resources/icons/settings/battery@2x.png differ
diff --git a/Telegram/Resources/icons/settings/battery@3x.png b/Telegram/Resources/icons/settings/battery@3x.png
new file mode 100644
index 000000000..2c1fe9a28
Binary files /dev/null and b/Telegram/Resources/icons/settings/battery@3x.png differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index bcdd1e01c..4c8916d70 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -608,7 +608,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_settings_security_bots" = "Bots and websites";
 "lng_settings_clear_payment_info" = "Clear Payment and Shipping Info";
 
-"lng_settings_power_title" = "Power efficiency";
+"lng_settings_power_menu" = "Battery and animations";
+"lng_settings_power_title" = "Power Usage";
+"lng_settings_power_subtitle" = "Power saving options";
 "lng_settings_power_stickers" = "Animated Stickers";
 "lng_settings_power_stickers_panel" = "Autoplay in panel";
 "lng_settings_power_stickers_chat" = "Autoplay in chat";
@@ -621,6 +623,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_settings_power_chat_spoiler" = "Animated spoiler effect";
 "lng_settings_power_calls" = "Animations in Calls";
 "lng_settings_power_ui" = "Interface animations";
+"lng_settings_power_auto" = "Save Power on Low Battery";
+"lng_settings_power_auto_about" = "Automatically disable all animations when your laptop is in a battery saving mode.";
 
 "lng_settings_cloud_password_on" = "On";
 "lng_settings_cloud_password_off" = "Off";
diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
index fc1b949cb..7006606ce 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
@@ -297,7 +297,7 @@ void EditAdminBox::prepare() {
 			& (filterByMyRights ? channel->adminRights() : ~Flag(0)));
 
 	const auto disabledMessages = [&] {
-		auto result = std::map<Flags, QString>();
+		auto result = base::flat_map<Flags, QString>();
 		if (!canSave()) {
 			result.emplace(
 				~Flags(0),
@@ -725,7 +725,7 @@ void EditRestrictedBox::prepare() {
 			? (Flag::ChangeInfo | Flag::PinMessages)
 			: Flags(0)));
 	const auto disabledMessages = [&] {
-		auto result = std::map<Flags, QString>();
+		auto result = base::flat_map<Flags, QString>();
 		if (!canSave()) {
 			result.emplace(
 				~Flags(0),
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
index 421d3eb12..a32758489 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
@@ -48,18 +48,12 @@ constexpr auto kSuggestGigagroupThreshold = 199000;
 	return {};
 }
 
-struct NestedRestrictionLabels {
-	std::optional<rpl::producer<QString>> nestedLabel;
-	std::vector<RestrictionLabel> restrictionLabels;
-};
-
 [[nodiscard]] auto NestedRestrictionLabelsList(
 		Data::RestrictionsSetOptions options) {
 	using Flag = ChatRestriction;
 
 	auto first = std::vector<RestrictionLabel>{
 		{ Flag::SendOther, tr::lng_rights_chat_send_text(tr::now) },
-		// { Flag::SendMedia, tr::lng_rights_chat_send_media(tr::now) },
 	};
 	auto inner = std::vector<RestrictionLabel>{
 		{ Flag::SendPhotos, tr::lng_rights_chat_photos(tr::now) },
@@ -89,7 +83,7 @@ struct NestedRestrictionLabels {
 				&RestrictionLabel::flags),
 			end(second));
 	}
-	return std::vector<NestedRestrictionLabels>{
+	return std::vector<NestedEditFlagsLabels<ChatRestrictions>>{
 		{ std::nullopt, std::move(first) },
 		{ tr::lng_rights_chat_send_media(), std::move(inner) },
 		{ std::nullopt, std::move(second) },
@@ -267,19 +261,24 @@ ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
 
 not_null<Ui::RpWidget*> AddInnerToggle(
 		not_null<Ui::VerticalLayout*> container,
+		const style::SettingsButton &st,
 		std::vector<not_null<Ui::AbstractCheckView*>> innerCheckViews,
 		not_null<Ui::SlideWrap<>*> wrap,
 		rpl::producer<QString> buttonLabel,
-		std::optional<QString> locked) {
-	const auto &stButton = st::rightsButton;
+		std::optional<QString> locked,
+		Settings::IconDescriptor &&icon) {
 	const auto button = container->add(object_ptr<Ui::SettingsButton>(
 		container,
 		nullptr,
-		stButton));
+		st));
+	if (icon) {
+		Settings::AddButtonIcon(button, st, std::move(icon));
+	}
+
 	const auto toggleButton = Ui::CreateChild<Ui::SettingsButton>(
 		container.get(),
 		nullptr,
-		stButton);
+		st);
 
 	struct State final {
 		State(const style::Toggle &st, Fn<void()> c)
@@ -291,7 +290,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 		std::vector<not_null<Ui::AbstractCheckView*>> innerChecks;
 	};
 	const auto state = button->lifetime().make_state<State>(
-		stButton.toggle,
+		st.toggle,
 		[=] { toggleButton->update(); });
 	state->innerChecks = std::move(innerCheckViews);
 	const auto countChecked = [=] {
@@ -309,12 +308,12 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 	{
 		const auto separator = Ui::CreateChild<Ui::RpWidget>(container.get());
 		separator->paintRequest(
-		) | rpl::start_with_next([=, bg = stButton.textBgOver] {
+		) | rpl::start_with_next([=, bg = st.textBgOver] {
 			auto p = QPainter(separator);
 			p.fillRect(separator->rect(), bg);
 		}, separator->lifetime());
-		const auto separatorHeight = 2 * stButton.toggle.border
-			+ stButton.toggle.diameter;
+		const auto separatorHeight = 2 * st.toggle.border
+			+ st.toggle.diameter;
 		button->geometryValue(
 		) | rpl::start_with_next([=](const QRect &r) {
 			const auto w = st::rightsButtonToggleWidth;
@@ -341,7 +340,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 		toggleButton->sizeValue(
 		) | rpl::start_with_next([=](const QSize &s) {
 			checkWidget->moveToRight(
-				stButton.toggleSkip,
+				st.toggleSkip,
 				(s.height() - checkWidget->height()) / 2);
 		}, toggleButton->lifetime());
 	}
@@ -392,8 +391,8 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 		}, arrow->lifetime());
 	}
 	button->sizeValue(
-	) | rpl::start_with_next([=](const QSize &s) {
-		const auto labelLeft = stButton.padding.left();
+	) | rpl::start_with_next([=, &st](const QSize &s) {
+		const auto labelLeft = st.padding.left();
 		const auto labelRight = s.width() - toggleButton->width();
 
 		label->resizeToWidth(labelRight - labelLeft - arrow->width());
@@ -446,22 +445,18 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 	return button;
 }
 
-template <
-	typename Flags,
-	typename DisabledMessagePairs,
-	typename FlagLabelPairs>
-[[nodiscard]] EditFlagsControl<Flags, Ui::RpWidget> CreateEditFlags(
+template <typename Flags>
+[[nodiscard]] EditFlagsControl<Flags> CreateEditFlags(
 		not_null<Ui::VerticalLayout*> container,
-		rpl::producer<QString> header,
 		Flags checked,
-		const DisabledMessagePairs &disabledMessagePairs,
-		const FlagLabelPairs &flagLabelPairsNested) {
+		EditFlagsDescriptor<Flags> &&descriptor) {
 	struct State final {
 		std::map<Flags, not_null<Ui::AbstractCheckView*>> checkViews;
 		rpl::event_stream<> anyChanges;
 	};
 	const auto state = container->lifetime().make_state<State>();
 
+	const auto &st = descriptor.st ? *descriptor.st : st::rightsButton;
 	const auto value = [=] {
 		auto result = Flags(0);
 		for (const auto &[flags, checkView] : state->checkViews) {
@@ -478,23 +473,23 @@ template <
 		ApplyDependencies(state->checkViews, dependencies, view);
 	};
 
-	if (header) {
+	if (descriptor.header) {
 		container->add(
 			object_ptr<Ui::FlatLabel>(
 				container,
-				std::move(header),
+				std::move(descriptor.header),
 				st::rightsHeaderLabel),
 			st::rightsHeaderMargin);
 	}
 	const auto addCheckbox = [&](
 			not_null<Ui::VerticalLayout*> verticalLayout,
 			bool isInner,
-			Flags flags,
-			const QString &text) {
+			const EditFlagsLabel<Flags> &entry) {
+		const auto flags = entry.flags;
 		const auto lockedIt = ranges::find_if(
-			disabledMessagePairs,
+			descriptor.disabledMessages,
 			[&](const auto &pair) { return (pair.first & flags) != 0; });
-		const auto locked = (lockedIt != end(disabledMessagePairs))
+		const auto locked = (lockedIt != end(descriptor.disabledMessages))
 			? std::make_optional(lockedIt->second)
 			: std::nullopt;
 		const auto toggled = ((checked & flags) != 0);
@@ -504,10 +499,10 @@ template <
 				const auto checkbox = verticalLayout->add(
 					object_ptr<Ui::Checkbox>(
 						verticalLayout,
-						text,
+						entry.label,
 						toggled,
 						st::settingsCheckbox),
-					st::rightsButton.padding);
+					st.padding);
 				const auto button = Ui::CreateChild<Ui::RippleButton>(
 					verticalLayout.get(),
 					st::defaultRippleAnimation);
@@ -530,13 +525,14 @@ template <
 			} else {
 				const auto button = Settings::AddButton(
 					verticalLayout,
-					rpl::single(text),
-					st::rightsButton);
+					rpl::single(entry.label),
+					st,
+					{ entry.icon });
 				const auto toggle = Ui::CreateChild<Ui::RpWidget>(
 					button.get());
 				auto &lifetime = toggle->lifetime();
 				const auto checkView = lifetime.make_state<Ui::ToggleView>(
-					st::rightsButton.toggle,
+					st.toggle,
 					toggled,
 					[=] { toggle->update(); });
 				toggle->resize(checkView->getSize());
@@ -548,7 +544,7 @@ template <
 				button->sizeValue(
 				) | rpl::start_with_next([=](const QSize &s) {
 					toggle->moveToRight(
-						st::rightsButton.toggleSkip,
+						st.toggleSkip,
 						(s.height() - toggle->height()) / 2);
 				}, toggle->lifetime());
 				button->setClickedCallback([=] {
@@ -581,8 +577,10 @@ template <
 
 		return checkView;
 	};
-	for (const auto &[nestedLabel, flagLabelPairs] : flagLabelPairsNested) {
-		const auto isInner = nestedLabel.has_value();
+	for (const auto &nestedWithLabel : descriptor.labels) {
+		Assert(!nestedWithLabel.nested.empty());
+
+		const auto isInner = nestedWithLabel.nestingLabel.has_value();
 		auto wrap = isInner
 			? object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
 				container,
@@ -590,8 +588,8 @@ template <
 			: object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>{ nullptr };
 		const auto verticalLayout = wrap ? wrap->entity() : container.get();
 		auto innerChecks = std::vector<not_null<Ui::AbstractCheckView*>>();
-		for (const auto &[flags, label] : flagLabelPairs) {
-			const auto c = addCheckbox(verticalLayout, isInner, flags, label);
+		for (const auto &entry : nestedWithLabel.nested) {
+			const auto c = addCheckbox(verticalLayout, isInner, entry);
 			if (isInner) {
 				innerChecks.push_back(c);
 			}
@@ -601,10 +599,12 @@ template <
 			raw->hide(anim::type::instant);
 			AddInnerToggle(
 				container,
+				st,
 				innerChecks,
 				raw,
-				*nestedLabel,
-				std::nullopt);
+				*nestedWithLabel.nestingLabel,
+				std::nullopt,
+				{ nestedWithLabel.nested.front().icon });
 			container->add(std::move(wrap));
 			container->widthValue(
 			) | rpl::start_with_next([=](int w) {
@@ -857,10 +857,10 @@ void ShowEditPeerPermissionsBox(
 		Unexpected("User in EditPeerPermissionsBox.");
 	}());
 	const auto disabledMessages = [&] {
-		auto result = std::map<Flags, QString>();
-			result.emplace(
-				disabledByAdminRights,
-				tr::lng_rights_permission_cant_edit(tr::now));
+		auto result = base::flat_map<Flags, QString>();
+		result.emplace(
+			disabledByAdminRights,
+			tr::lng_rights_permission_cant_edit(tr::now));
 		if (const auto channel = peer->asChannel()) {
 			if (channel->isPublic()
 				|| (channel->isMegagroup() && channel->linkedChat())) {
@@ -1026,19 +1026,21 @@ std::vector<AdminRightLabel> AdminRightLabels(
 	}
 }
 
-EditFlagsControl<ChatRestrictions, Ui::RpWidget> CreateEditRestrictions(
+EditFlagsControl<ChatRestrictions> CreateEditRestrictions(
 		QWidget *parent,
 		rpl::producer<QString> header,
 		ChatRestrictions restrictions,
-		std::map<ChatRestrictions, QString> disabledMessages,
+		base::flat_map<ChatRestrictions, QString> disabledMessages,
 		Data::RestrictionsSetOptions options) {
 	auto widget = object_ptr<Ui::VerticalLayout>(parent);
 	auto result = CreateEditFlags(
 		widget.data(),
-		header,
 		NegateRestrictions(restrictions),
-		disabledMessages,
-		NestedRestrictionLabelsList(options));
+		{
+			.header = std::move(header),
+			.labels = NestedRestrictionLabelsList(options),
+			.disabledMessages = std::move(disabledMessages),
+		});
 	result.widget = std::move(widget);
 	result.value = [original = std::move(result.value)]{
 		return NegateRestrictions(original());
@@ -1050,22 +1052,21 @@ EditFlagsControl<ChatRestrictions, Ui::RpWidget> CreateEditRestrictions(
 	return result;
 }
 
-EditFlagsControl<ChatAdminRights, Ui::RpWidget> CreateEditAdminRights(
+EditFlagsControl<ChatAdminRights> CreateEditAdminRights(
 		QWidget *parent,
 		rpl::producer<QString> header,
 		ChatAdminRights rights,
-		std::map<ChatAdminRights, QString> disabledMessages,
+		base::flat_map<ChatAdminRights, QString> disabledMessages,
 		Data::AdminRightsSetOptions options) {
-	using String = std::optional<rpl::producer<QString>>;
-	using Labels = std::pair<String, std::vector<AdminRightLabel>>;
-
 	auto widget = object_ptr<Ui::VerticalLayout>(parent);
 	auto result = CreateEditFlags(
 		widget.data(),
-		header,
 		rights,
-		disabledMessages,
-		std::vector<Labels>{ { std::nullopt, AdminRightLabels(options) } });
+		{
+			.header = std::move(header),
+			.labels = { { std::nullopt, AdminRightLabels(options) } },
+			.disabledMessages = std::move(disabledMessages),
+		});
 	result.widget = std::move(widget);
 
 	return result;
@@ -1130,24 +1131,22 @@ ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions) {
 ChatAdminRights AdminRightsForOwnershipTransfer(
 		Data::AdminRightsSetOptions options) {
 	auto result = ChatAdminRights();
-	for (const auto &[flag, label] : AdminRightLabels(options)) {
-		if (!(flag & ChatAdminRight::Anonymous)) {
-			result |= flag;
+	for (const auto &entry : AdminRightLabels(options)) {
+		if (!(entry.flags & ChatAdminRight::Anonymous)) {
+			result |= entry.flags;
 		}
 	}
 	return result;
 }
 
-EditFlagsControl<PowerSaving::Flags, Ui::RpWidget> CreateEditPowerSaving(
+EditFlagsControl<PowerSaving::Flags> CreateEditPowerSaving(
 		QWidget *parent,
 		PowerSaving::Flags flags) {
 	auto widget = object_ptr<Ui::VerticalLayout>(parent);
 	auto result = CreateEditFlags(
 		widget.data(),
-		nullptr,
 		flags,
-		std::map<PowerSaving::Flags, QString>{},
-		Settings::PowerSavingLabelsList());
+		Settings::PowerSavingLabels());
 	result.widget = std::move(widget);
 
 	return result;
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
index 75d806dea..0cc1d0ed8 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
@@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include "data/data_chat_participant_status.h"
 
+namespace style {
+struct SettingsButton;
+} // namespace style
+
 namespace Ui {
 class GenericBox;
 class RoundButton;
@@ -44,42 +48,57 @@ void ShowEditPeerPermissionsBox(
 	not_null<ChannelData*> channel,
 	not_null<Window::SessionController*> controller);
 
-struct RestrictionLabel {
-	ChatRestrictions flags;
+template <typename Flags>
+struct EditFlagsLabel {
+	Flags flags;
 	QString label;
+	const style::icon *icon = nullptr;
 };
-[[nodiscard]] std::vector<RestrictionLabel> RestrictionLabels(
-	Data::RestrictionsSetOptions options);
 
-struct AdminRightLabel {
-	ChatAdminRights flags;
-	QString label;
-};
-[[nodiscard]] std::vector<AdminRightLabel> AdminRightLabels(
-	Data::AdminRightsSetOptions options);
-
-template <typename Flags, typename Widget>
+template <typename Flags>
 struct EditFlagsControl {
-	object_ptr<Widget> widget;
+	object_ptr<Ui::RpWidget> widget;
 	Fn<Flags()> value;
 	rpl::producer<Flags> changes;
 };
 
+template <typename Flags>
+struct NestedEditFlagsLabels {
+	std::optional<rpl::producer<QString>> nestingLabel;
+	std::vector<EditFlagsLabel<Flags>> nested;
+};
+
+template <typename Flags>
+struct EditFlagsDescriptor {
+	rpl::producer<QString> header;
+	std::vector<NestedEditFlagsLabels<Flags>> labels;
+	base::flat_map<Flags, QString> disabledMessages;
+	const style::SettingsButton *st = nullptr;
+};
+
+using RestrictionLabel = EditFlagsLabel<ChatRestrictions>;
+[[nodiscard]] std::vector<RestrictionLabel> RestrictionLabels(
+	Data::RestrictionsSetOptions options);
+
+using AdminRightLabel = EditFlagsLabel<ChatAdminRights>;
+[[nodiscard]] std::vector<AdminRightLabel> AdminRightLabels(
+	Data::AdminRightsSetOptions options);
+
 [[nodiscard]] auto CreateEditRestrictions(
 	QWidget *parent,
 	rpl::producer<QString> header,
 	ChatRestrictions restrictions,
-	std::map<ChatRestrictions, QString> disabledMessages,
+	base::flat_map<ChatRestrictions, QString> disabledMessages,
 	Data::RestrictionsSetOptions options)
--> EditFlagsControl<ChatRestrictions, Ui::RpWidget>;
+-> EditFlagsControl<ChatRestrictions>;
 
 [[nodiscard]] auto CreateEditAdminRights(
 	QWidget *parent,
 	rpl::producer<QString> header,
 	ChatAdminRights rights,
-	std::map<ChatAdminRights, QString> disabledMessages,
+	base::flat_map<ChatAdminRights, QString> disabledMessages,
 	Data::AdminRightsSetOptions options)
--> EditFlagsControl<ChatAdminRights, Ui::RpWidget>;
+-> EditFlagsControl<ChatAdminRights>;
 
 [[nodiscard]] ChatAdminRights DisabledByDefaultRestrictions(
 	not_null<PeerData*> peer);
@@ -91,4 +110,4 @@ struct EditFlagsControl {
 [[nodiscard]] auto CreateEditPowerSaving(
 	QWidget *parent,
 	PowerSaving::Flags flags
-) -> EditFlagsControl<PowerSaving::Flags, Ui::RpWidget>;
+) -> EditFlagsControl<PowerSaving::Flags>;
diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style
index 76b5b9dc6..e2a72af3b 100644
--- a/Telegram/SourceFiles/settings/settings.style
+++ b/Telegram/SourceFiles/settings/settings.style
@@ -81,6 +81,7 @@ settingsIconFolders: icon {{ "settings/folders", settingsIconFg }};
 settingsIconGeneral: icon {{ "settings/advanced", settingsIconFg }};
 settingsIconLock: icon {{ "settings/lock", settingsIconFg }};
 settingsIconLanguage: icon {{ "settings/language", settingsIconFg }};
+settingsIconBattery: icon {{ "settings/battery", settingsIconFg }};
 settingsIconInterfaceScale: icon {{ "settings/interface_scale", settingsIconFg }};
 settingsIconFaq: icon {{ "settings/faq", settingsIconFg }};
 settingsIconCalls: icon {{ "settings/calls", settingsIconFg }};
@@ -526,3 +527,13 @@ requestPeerRestriction: FlatLabel(defaultFlatLabel) {
 		lineHeight: 22px;
 	}
 }
+
+powerSavingButton: SettingsButton(settingsButton) {
+	style: boxTextStyle;
+	padding: margins(57px, 8px, 22px, 8px);
+	iconLeft: 20px;
+}
+powerSavingButtonNoIcon: SettingsButton(powerSavingButton) {
+	padding: margins(22px, 8px, 22px, 8px);
+}
+powerSavingSubtitlePadding: margins(0px, 4px, 0px, -2px);
diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp
index 3fe1c256f..4c6ef2284 100644
--- a/Telegram/SourceFiles/settings/settings_advanced.cpp
+++ b/Telegram/SourceFiles/settings/settings_advanced.cpp
@@ -664,7 +664,7 @@ void SetupAnimations(
 		not_null<Ui::VerticalLayout*> container) {
 	AddButton(
 		container,
-		tr::lng_settings_power_title(),
+		tr::lng_settings_power_menu(),
 		st::settingsButtonNoIcon
 	)->setClickedCallback([=] {
 		window->show(Box(PowerSavingBox));
diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp
index 7bd0e0983..f2144d1cc 100644
--- a/Telegram/SourceFiles/settings/settings_common.cpp
+++ b/Telegram/SourceFiles/settings/settings_common.cpp
@@ -60,11 +60,12 @@ base::options::toggle OptionMonoSettingsIcons({
 const char kOptionMonoSettingsIcons[] = "mono-settings-icons";
 
 Icon::Icon(IconDescriptor descriptor) : _icon(descriptor.icon) {
-	const auto background = [&] {
-		if (OptionMonoSettingsIcons.value()) {
+	const auto background = [&]() -> const style::color* {
+		if (descriptor.type == IconType::Simple) {
+			return nullptr;
+		} else if (OptionMonoSettingsIcons.value()) {
 			return &st::transparent;
-		}
-		if (descriptor.color > 0) {
+		} else if (descriptor.color > 0) {
 			const auto list = std::array{
 				&st::settingsIconBg1,
 				&st::settingsIconBg2,
diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h
index e0dffe917..9ee703093 100644
--- a/Telegram/SourceFiles/settings/settings_common.h
+++ b/Telegram/SourceFiles/settings/settings_common.h
@@ -141,6 +141,7 @@ inline constexpr auto kIconGray = 9;
 enum class IconType {
 	Rounded,
 	Round,
+	Simple,
 };
 
 struct IconDescriptor {
diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp
index f12f2e81e..39fd8133d 100644
--- a/Telegram/SourceFiles/settings/settings_main.cpp
+++ b/Telegram/SourceFiles/settings/settings_main.cpp
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "settings/settings_advanced.h"
 #include "settings/settings_folders.h"
 #include "settings/settings_calls.h"
+#include "settings/settings_power_saving.h"
 #include "settings/settings_premium.h"
 #include "settings/settings_scale_preview.h"
 #include "boxes/language_box.h"
@@ -257,6 +258,19 @@ void Cover::refreshUsernameGeometry(int newWidth) {
 
 } // namespace
 
+void SetupPowerSavingButton(
+		not_null<Window::Controller*> window,
+		not_null<Ui::VerticalLayout*> container) {
+	const auto button = AddButton(
+		container,
+		tr::lng_settings_power_menu(),
+		st::settingsButton,
+		{ &st::settingsIconBattery, kIconDarkOrange });
+	button->setClickedCallback([=] {
+		window->show(Box(PowerSavingBox));
+	});
+}
+
 void SetupLanguageButton(
 		not_null<Window::Controller*> window,
 		not_null<Ui::VerticalLayout*> container,
@@ -270,7 +284,7 @@ void SetupLanguageButton(
 			Lang::GetInstance().idChanges()
 		) | rpl::map([] { return Lang::GetInstance().nativeName(); }),
 		icon ? st::settingsButton : st::settingsButtonNoIcon,
-		{ icon ? &st::settingsIconLanguage : nullptr, kIconDarkOrange });
+		{ icon ? &st::settingsIconLanguage : nullptr, kIconLightBlue });
 	const auto guard = Ui::CreateChild<base::binary_guard>(button.get());
 	button->addClickHandler([=] {
 		const auto m = button->clickModifiers();
@@ -381,6 +395,7 @@ void SetupSections(
 		Calls::Id(),
 		{ &st::settingsIconCalls, kIconGreen });
 
+	SetupPowerSavingButton(&controller->window(), container);
 	SetupLanguageButton(&controller->window(), container);
 
 	if (controller->session().premiumPossible()) {
diff --git a/Telegram/SourceFiles/settings/settings_power_saving.cpp b/Telegram/SourceFiles/settings/settings_power_saving.cpp
index 88cc2829e..bd75ebbf7 100644
--- a/Telegram/SourceFiles/settings/settings_power_saving.cpp
+++ b/Telegram/SourceFiles/settings/settings_power_saving.cpp
@@ -10,13 +10,31 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "boxes/peers/edit_peer_permissions_box.h"
 #include "core/application.h"
 #include "lang/lang_keys.h"
+#include "settings/settings_common.h"
 #include "ui/layers/generic_box.h"
+#include "ui/widgets/buttons.h"
 #include "ui/power_saving.h"
+#include "styles/style_menu_icons.h"
+#include "styles/style_layers.h"
+#include "styles/style_settings.h"
 
 namespace Settings {
 
 void PowerSavingBox(not_null<Ui::GenericBox*> box) {
+	box->setStyle(st::layerBox);
 	box->setTitle(tr::lng_settings_power_title());
+	box->setWidth(st::boxWideWidth);
+
+	const auto container = box->verticalLayout();
+
+	// Force top shadow visibility.
+	box->setPinnedToTopContent(
+		object_ptr<Ui::FixedHeightWidget>(box, st::lineWidth));
+
+	AddSubsectionTitle(
+		container,
+		tr::lng_settings_power_subtitle(),
+		st::powerSavingSubtitlePadding);
 
 	auto [checkboxes, getResult, changes] = CreateEditPowerSaving(
 		box,
@@ -24,6 +42,22 @@ void PowerSavingBox(not_null<Ui::GenericBox*> box) {
 
 	box->addRow(std::move(checkboxes), {});
 
+	auto automatic = (Ui::SettingsButton*)nullptr;
+	const auto hasBattery = true;
+	const auto automaticEnabled = true;
+	if (hasBattery) {
+		AddSkip(container);
+		AddDivider(container);
+		AddSkip(container);
+		AddButton(
+			container,
+			tr::lng_settings_power_auto(),
+			st::powerSavingButtonNoIcon
+		)->toggleOn(rpl::single(automaticEnabled));
+		AddSkip(container);
+		AddDividerText(container, tr::lng_settings_power_auto_about());
+	}
+
 	box->addButton(tr::lng_settings_save(), [=, collect = getResult] {
 		Set(PowerSaving::kAll & ~collect());
 		Core::App().saveSettingsDelayed();
@@ -32,35 +66,56 @@ void PowerSavingBox(not_null<Ui::GenericBox*> box) {
 	box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
 }
 
-std::vector<NestedPowerSavingLabels> PowerSavingLabelsList() {
+EditFlagsDescriptor<PowerSaving::Flags> PowerSavingLabels() {
 	using namespace PowerSaving;
-	using Label = PowerSavingLabel;
+	using Label = EditFlagsLabel<Flags>;
+
 	auto stickers = std::vector<Label>{
-		{ kStickersPanel, tr::lng_settings_power_stickers_panel(tr::now) },
+		{
+			kStickersPanel,
+			tr::lng_settings_power_stickers_panel(tr::now),
+			&st::menuIconStickers,
+		},
 		{ kStickersChat, tr::lng_settings_power_stickers_chat(tr::now) },
 	};
 	auto emoji = std::vector<Label>{
-		{ kEmojiPanel, tr::lng_settings_power_emoji_panel(tr::now) },
+		{
+			kEmojiPanel,
+			tr::lng_settings_power_emoji_panel(tr::now),
+			&st::menuIconEmoji,
+		},
 		{ kEmojiReactions, tr::lng_settings_power_emoji_reactions(tr::now) },
 		{ kEmojiChat, tr::lng_settings_power_emoji_chat(tr::now) },
 	};
 	auto chat = std::vector<Label>{
-		{ kChatBackground, tr::lng_settings_power_chat_background(tr::now) },
+		{
+			kChatBackground,
+			tr::lng_settings_power_chat_background(tr::now),
+			&st::menuIconChatBubble,
+		},
 		{ kChatSpoiler, tr::lng_settings_power_chat_spoiler(tr::now) },
 	};
 	auto calls = std::vector<Label>{
-		{ kCalls, tr::lng_settings_power_calls(tr::now) },
+		{
+			kCalls,
+			tr::lng_settings_power_calls(tr::now),
+			&st::menuIconPhone,
+		},
 	};
 	auto animations = std::vector<Label>{
-		{ kAnimations, tr::lng_settings_power_ui(tr::now) },
+		{
+			kAnimations,
+			tr::lng_settings_power_ui(tr::now),
+			&st::menuIconStartStream,
+		},
 	};
-	return {
+	return { .labels = {
 		{ tr::lng_settings_power_stickers(), std::move(stickers) },
 		{ tr::lng_settings_power_emoji(), std::move(emoji) },
 		{ tr::lng_settings_power_chat(), std::move(chat) },
 		{ std::nullopt, std::move(calls) },
-		{ std::nullopt, std::move(animations) },
-	};
+		{ std::nullopt, std::move(animations),  },
+	}, .st = &st::powerSavingButton };
 }
 
 } // namespace Settings
diff --git a/Telegram/SourceFiles/settings/settings_power_saving.h b/Telegram/SourceFiles/settings/settings_power_saving.h
index d29e78cde..22d559b56 100644
--- a/Telegram/SourceFiles/settings/settings_power_saving.h
+++ b/Telegram/SourceFiles/settings/settings_power_saving.h
@@ -7,8 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 */
 #pragma once
 
+#include "base/flags.h"
+
+template <typename Flags>
+struct EditFlagsDescriptor;
+
 namespace PowerSaving {
 enum Flag : uint32;
+using Flags = base::flags<Flag>;
 } // namespace PowerSaving
 
 namespace Ui {
@@ -19,16 +25,6 @@ namespace Settings {
 
 void PowerSavingBox(not_null<Ui::GenericBox*> box);
 
-struct PowerSavingLabel {
-	PowerSaving::Flag flags;
-	QString label;
-};
-
-struct NestedPowerSavingLabels {
-	std::optional<rpl::producer<QString>> nestedLabel;
-	std::vector<PowerSavingLabel> restrictionLabels;
-};
-
-[[nodiscard]] std::vector<NestedPowerSavingLabels> PowerSavingLabelsList();
+[[nodiscard]] EditFlagsDescriptor<PowerSaving::Flags> PowerSavingLabels();
 
 } // namespace PowerSaving
diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style
index 142cc47f0..cf78f2bdc 100644
--- a/Telegram/SourceFiles/ui/menu_icons.style
+++ b/Telegram/SourceFiles/ui/menu_icons.style
@@ -20,6 +20,7 @@ menuIconDelete: icon {{ "menu/delete", menuIconColor }};
 menuIconSelect: icon {{ "menu/select", menuIconColor }};
 menuIconSaveImage: icon {{ "menu/save_image", menuIconColor }};
 menuIconStickers: icon {{ "menu/stickers", menuIconColor }};
+menuIconEmoji: icon {{ "menu/emoji", menuIconColor }};
 menuIconCancel: icon {{ "menu/cancel", menuIconColor }};
 menuIconShowInChat: icon {{ "menu/show_in_chat", menuIconColor }};
 menuIconGif: icon {{ "menu/gif", menuIconColor }};
@@ -100,6 +101,8 @@ menuIconDisable: icon {{ "menu/disable", menuIconColor }};
 menuIconPhotoSet: icon {{ "menu/photo_set", menuIconColor }};
 menuIconPhotoSuggest: icon {{ "menu/photo_suggest", menuIconColor }};
 menuIconNewWindow: icon {{ "menu/new_window", menuIconColor }};
+menuIconChatBubble: icon {{ "menu/chat_bubble", menuIconColor }};
+menuIconPhone: icon {{ "menu/phone", menuIconColor }};
 
 menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
 menuIconTTLAnyTextPosition: point(11px, 22px);