Make the slot machine its own sidebar entry; rework its visuals

Moves Slot Machine into the sidebar's account section (alongside RZ
Shop/Settings/Log out) instead of being reachable only from the shop -
removes the shop's promo banner and the screen's "Back to Shop" link
accordingly.

Also closes a chunk of the visual gap against the mockup: a proper
cabinet-style panel (arched top corners, glowing border), a light
"screen" panel holding a real 3x3 reel grid instead of 3 single icons,
a decorative lever, an "RZ" marquee, and the cost/spin/auto-spin
controls each in their own bordered box. Added two new vendored icons
(gem, flask-conical) for reel variety and reward-list icons.
This commit is contained in:
hz
2026-07-30 01:20:24 -05:00
parent 1860e6ede6
commit bcb411bed8
9 changed files with 294 additions and 118 deletions
+15
View File
@@ -0,0 +1,15 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#ffffff"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M10 2v6.29a2 2 0 0 1-.5 1.32L3.9 17.8A2 2 0 0 0 5.4 21h13.2a2 2 0 0 0 1.5-3.2l-5.6-8.19A2 2 0 0 1 14 8.29V2" />
<path d="M6.5 15h11" />
<path d="M8.5 2h7" />
</svg>

After

Width:  |  Height:  |  Size: 376 B

@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c2ud26rg3exo1"
path="res://.godot/imported/flask-conical.svg-f4d9011dce33718bd3c2a0f719a8656a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/lucide/flask-conical.svg"
dest_files=["res://.godot/imported/flask-conical.svg-f4d9011dce33718bd3c2a0f719a8656a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+15
View File
@@ -0,0 +1,15 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#ffffff"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M6 3h12l4 6-10 12L2 9Z" />
<path d="M11 3 8 9l4 12 4-12-3-6" />
<path d="M2 9h20" />
</svg>

After

Width:  |  Height:  |  Size: 303 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://caty3viul0634"
path="res://.godot/imported/gem.svg-33acfe3fd8cfb097f65cc061d34abd2e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/lucide/gem.svg"
dest_files=["res://.godot/imported/gem.svg-33acfe3fd8cfb097f65cc061d34abd2e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+2
View File
@@ -445,6 +445,7 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void
_add_nav_button(container, "donations", "Support RanaZe", "heart-pulse", true)
_add_nav_button(container, "performance", "Profile", "user-round", true)
_add_nav_button(container, "rz_store", "RZ Shop", "star", true)
_add_nav_button(container, "slot_machine", "Slot Machine", "gem", true)
_add_nav_button(container, "settings", "Settings", "settings", true)
_add_nav_button(container, "logout", "Log out", "log-out", true)
@@ -489,6 +490,7 @@ func _on_navigation_pressed(key: String) -> void:
"bookmarks": show_screen("bookmarks")
"donations": show_screen("donations")
"rz_store": show_screen("rz_store")
"slot_machine": show_screen("slot_machine")
"logout": _logout()
+1 -1
View File
@@ -32,5 +32,5 @@ static func key_for_screen(screen_name: String, payload: Variant = null) -> Stri
elif screen_name == "rz_store":
key = "rz_store"
elif screen_name == "slot_machine":
key = "rz_store"
key = "slot_machine"
return key
+174 -51
View File
@@ -5,11 +5,13 @@ const STAR_ICON := preload("res://assets/icons/lucide/star.svg")
const SHIELD_ICON := preload("res://assets/icons/lucide/shield.svg")
const CLOCK_ICON := preload("res://assets/icons/lucide/clock-3.svg")
const RESET_ICON := preload("res://assets/icons/lucide/rotate-ccw.svg")
const REEL_SYMBOLS := [STAR_ICON, SHIELD_ICON, CLOCK_ICON, RESET_ICON]
const GEM_ICON := preload("res://assets/icons/lucide/gem.svg")
const FLASK_ICON := preload("res://assets/icons/lucide/flask-conical.svg")
const REEL_SYMBOLS := [STAR_ICON, SHIELD_ICON, CLOCK_ICON, RESET_ICON, GEM_ICON, FLASK_ICON]
const ICON_BY_REWARD_KEY := {
"jackpot": "star",
"epic": "star",
"great": "star",
"epic": "gem",
"great": "shield",
"exam_token": "clock-3",
"qbank_reset": "rotate-ccw",
"nice": "star",
@@ -19,11 +21,13 @@ const ICON_BY_REWARD_KEY := {
var main: Control
var subtitle_label: Label
var back_button: Button
var machine_panel: PanelContainer
var reel_icons: Array = []
var reel_columns: Array = []
var win_up_to_card: PanelContainer
var win_up_to_label: Label
var cost_card: PanelContainer
var cost_value_label: Label
var auto_card: PanelContainer
var spin_button: Button
var auto_spin_toggle: CheckButton
var status_label: Label
@@ -74,14 +78,6 @@ func on_show(_payload: Variant = null) -> void:
func _build_header() -> void:
back_button = Button.new()
back_button.text = "← Back to Shop"
back_button.add_theme_font_override("font", Brand.font)
back_button.flat = true
back_button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
back_button.pressed.connect(func(): main.show_screen("rz_store"))
add_child(back_button)
var title := Label.new()
title.text = "RZ Coin Slot Machine"
title.add_theme_font_override("font", Brand.font)
@@ -99,55 +95,93 @@ func _build_machine(parent: Control) -> void:
var dark := UIThemeService.is_dark_mode()
machine_panel = PanelContainer.new()
machine_panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
machine_panel.add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
machine_panel.add_theme_stylebox_override("panel", _cabinet_box())
parent.add_child(machine_panel)
var margin := MarginContainer.new()
margin.add_theme_constant_override("margin_left", 20)
margin.add_theme_constant_override("margin_right", 20)
margin.add_theme_constant_override("margin_top", 18)
margin.add_theme_constant_override("margin_bottom", 18)
margin.add_theme_constant_override("margin_left", 24)
margin.add_theme_constant_override("margin_right", 24)
margin.add_theme_constant_override("margin_top", 22)
margin.add_theme_constant_override("margin_bottom", 22)
machine_panel.add_child(margin)
var column := VBoxContainer.new()
column.add_theme_constant_override("separation", 14)
column.add_theme_constant_override("separation", 16)
margin.add_child(column)
var reels_row := HBoxContainer.new()
reels_row.add_theme_constant_override("separation", 12)
reels_row.alignment = BoxContainer.ALIGNMENT_CENTER
column.add_child(reels_row)
_build_marquee(column)
reel_icons.clear()
for _i in range(3):
var reel_panel := PanelContainer.new()
reel_panel.custom_minimum_size = Vector2(84, 84)
reel_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 12))
var icon := TextureRect.new()
icon.texture = STAR_ICON
icon.modulate = Brand.AMBER
icon.custom_minimum_size = Vector2(40, 40)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
icon.size_flags_vertical = Control.SIZE_SHRINK_CENTER
reel_panel.add_child(icon)
reels_row.add_child(reel_panel)
reel_icons.append(icon)
var reel_row := HBoxContainer.new()
reel_row.add_theme_constant_override("separation", 16)
reel_row.alignment = BoxContainer.ALIGNMENT_CENTER
column.add_child(reel_row)
var reel_screen := PanelContainer.new()
reel_screen.add_theme_stylebox_override("panel", _reel_screen_box())
reel_row.add_child(reel_screen)
var reel_margin := MarginContainer.new()
reel_margin.add_theme_constant_override("margin_left", 16)
reel_margin.add_theme_constant_override("margin_right", 16)
reel_margin.add_theme_constant_override("margin_top", 14)
reel_margin.add_theme_constant_override("margin_bottom", 14)
reel_screen.add_child(reel_margin)
var reels_grid := HBoxContainer.new()
reels_grid.add_theme_constant_override("separation", 12)
reel_margin.add_child(reels_grid)
reel_columns.clear()
for _column_index in range(3):
var reel_col := VBoxContainer.new()
reel_col.add_theme_constant_override("separation", 8)
reels_grid.add_child(reel_col)
var cells: Array = []
for _row_index in range(3):
var icon := TextureRect.new()
icon.texture = STAR_ICON
icon.modulate = Brand.AMBER
icon.custom_minimum_size = Vector2(34, 34)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
reel_col.add_child(icon)
cells.append(icon)
reel_columns.append(cells)
reel_row.add_child(_build_lever())
win_up_to_card = PanelContainer.new()
win_up_to_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
column.add_child(win_up_to_card)
var win_margin := MarginContainer.new()
win_margin.add_theme_constant_override("margin_left", 14)
win_margin.add_theme_constant_override("margin_right", 14)
win_margin.add_theme_constant_override("margin_top", 10)
win_margin.add_theme_constant_override("margin_bottom", 10)
win_up_to_card.add_child(win_margin)
win_up_to_label = Label.new()
win_up_to_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
win_up_to_label.add_theme_font_override("font", Brand.font)
win_up_to_label.add_theme_font_size_override("font_size", 15)
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
column.add_child(win_up_to_label)
win_margin.add_child(win_up_to_label)
var controls_row := HBoxContainer.new()
controls_row.add_theme_constant_override("separation", 14)
controls_row.add_theme_constant_override("separation", 12)
column.add_child(controls_row)
cost_card = PanelContainer.new()
cost_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
controls_row.add_child(cost_card)
var cost_margin := MarginContainer.new()
cost_margin.add_theme_constant_override("margin_left", 14)
cost_margin.add_theme_constant_override("margin_right", 14)
cost_margin.add_theme_constant_override("margin_top", 8)
cost_margin.add_theme_constant_override("margin_bottom", 8)
cost_card.add_child(cost_margin)
var cost_box := VBoxContainer.new()
cost_box.add_theme_constant_override("separation", 0)
cost_margin.add_child(cost_box)
var cost_caption := Label.new()
cost_caption.text = "Cost per spin"
cost_caption.add_theme_font_override("font", Brand.font)
@@ -159,19 +193,30 @@ func _build_machine(parent: Control) -> void:
cost_value_label.add_theme_font_size_override("font_size", 15)
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
cost_box.add_child(cost_value_label)
controls_row.add_child(cost_box)
spin_button = Button.new()
spin_button.text = "Spin"
spin_button.custom_minimum_size = Vector2(120, 44)
spin_button.custom_minimum_size = Vector2(140, 58)
spin_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
spin_button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
spin_button.add_theme_font_override("font", Brand.font)
spin_button.add_theme_font_size_override("font_size", 17)
_style_spin_button()
spin_button.pressed.connect(_on_spin_pressed)
controls_row.add_child(spin_button)
auto_card = PanelContainer.new()
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
controls_row.add_child(auto_card)
var auto_margin := MarginContainer.new()
auto_margin.add_theme_constant_override("margin_left", 14)
auto_margin.add_theme_constant_override("margin_right", 14)
auto_margin.add_theme_constant_override("margin_top", 8)
auto_margin.add_theme_constant_override("margin_bottom", 8)
auto_card.add_child(auto_margin)
var auto_box := VBoxContainer.new()
auto_box.add_theme_constant_override("separation", 0)
auto_margin.add_child(auto_box)
auto_spin_toggle = CheckButton.new()
auto_spin_toggle.text = "Auto Spin"
auto_spin_toggle.add_theme_font_override("font", Brand.font)
@@ -182,7 +227,6 @@ func _build_machine(parent: Control) -> void:
auto_caption.add_theme_font_size_override("font_size", 11)
auto_caption.add_theme_color_override("font_color", Brand.muted_color(dark))
auto_box.add_child(auto_caption)
controls_row.add_child(auto_box)
var info_label := Label.new()
info_label.text = "All rewards are instant and sent to your account."
@@ -193,6 +237,80 @@ func _build_machine(parent: Control) -> void:
column.add_child(info_label)
func _build_marquee(column: VBoxContainer) -> void:
var row := HBoxContainer.new()
row.alignment = BoxContainer.ALIGNMENT_CENTER
row.add_theme_constant_override("separation", 12)
column.add_child(row)
row.add_child(_marquee_star())
var mark := Label.new()
mark.text = "RZ"
mark.add_theme_font_override("font", Brand.font)
mark.add_theme_font_size_override("font_size", 34)
mark.add_theme_color_override("font_color", Brand.SKY_BLUE)
row.add_child(mark)
row.add_child(_marquee_star())
func _marquee_star() -> TextureRect:
var star := TextureRect.new()
star.texture = STAR_ICON
star.modulate = Brand.SKY_BLUE
star.custom_minimum_size = Vector2(16, 16)
star.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
star.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
return star
func _build_lever() -> Control:
var wrap := VBoxContainer.new()
wrap.alignment = BoxContainer.ALIGNMENT_BEGIN
wrap.size_flags_vertical = Control.SIZE_EXPAND_FILL
wrap.add_theme_constant_override("separation", 0)
var knob := PanelContainer.new()
knob.custom_minimum_size = Vector2(22, 22)
knob.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
var knob_box := StyleBoxFlat.new()
knob_box.bg_color = Brand.ROYAL_BLUE
knob_box.set_corner_radius_all(11)
knob_box.corner_detail = 20
knob_box.anti_aliasing = false
knob.add_theme_stylebox_override("panel", knob_box)
wrap.add_child(knob)
var rod := ColorRect.new()
rod.color = Color("64748b")
rod.custom_minimum_size = Vector2(5, 90)
rod.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
wrap.add_child(rod)
return wrap
func _cabinet_box() -> StyleBoxFlat:
var box := StyleBoxFlat.new()
box.bg_color = Color("0b1220")
box.border_color = Brand.SKY_BLUE
box.set_border_width_all(3)
box.corner_radius_top_left = 48
box.corner_radius_top_right = 48
box.corner_radius_bottom_left = 16
box.corner_radius_bottom_right = 16
box.shadow_color = Color(Brand.SKY_BLUE, 0.35)
box.shadow_size = 10
return box
func _reel_screen_box() -> StyleBoxFlat:
var box := StyleBoxFlat.new()
box.bg_color = Color("e2e8f0")
box.border_color = Color("94a3b8")
box.set_border_width_all(2)
box.set_corner_radius_all(10)
return box
func _build_rewards_panel(parent: Control) -> void:
var dark := UIThemeService.is_dark_mode()
var panel := PanelContainer.new()
@@ -276,9 +394,11 @@ func _build_footer() -> void:
func _refresh_theme_controls() -> void:
var dark := UIThemeService.is_dark_mode()
subtitle_label.add_theme_color_override("font_color", Brand.muted_color(dark))
machine_panel.add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
win_up_to_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
win_up_to_label.add_theme_color_override("font_color", Brand.text_color(dark))
cost_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
cost_value_label.add_theme_color_override("font_color", Brand.text_color(dark))
auto_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 18))
footer_heading.add_theme_color_override("font_color", Brand.text_color(dark))
@@ -428,20 +548,23 @@ func _await_spin_result() -> Dictionary:
func _animate_reels() -> void:
for index in range(reel_icons.size()):
_spin_one_reel(reel_icons[index], 0.9 + index * 0.25)
for index in range(reel_columns.size()):
_spin_one_reel(reel_columns[index], 0.9 + index * 0.25)
func _spin_one_reel(icon: TextureRect, duration: float) -> void:
func _spin_one_reel(cells: Array, duration: float) -> void:
var elapsed := 0.0
var interval := 0.06
while elapsed < duration:
icon.texture = REEL_SYMBOLS[randi() % REEL_SYMBOLS.size()]
var symbol: Texture2D = REEL_SYMBOLS[randi() % REEL_SYMBOLS.size()]
for cell in cells:
cell.texture = symbol
await get_tree().create_timer(interval).timeout
elapsed += interval
interval = minf(interval * 1.18, 0.22)
icon.texture = STAR_ICON
icon.modulate = Brand.AMBER
for cell in cells:
cell.texture = STAR_ICON
cell.modulate = Brand.AMBER
func _play_coin_burst(coins_won: int) -> void:
+1
View File
@@ -0,0 +1 @@
uid://col1hauyr27rn
-66
View File
@@ -28,10 +28,6 @@ var balance_value_label: Label
var coin_caption_label: Label
var inventory_label: Label
var tab_controls: Array = []
var banner_card: PanelContainer
var banner_icon_panel: PanelContainer
var banner_heading: Label
var banner_description: Label
var section_heading: Label
var section_subtitle: Label
var products_grid: HFlowContainer
@@ -53,7 +49,6 @@ func _ready() -> void:
_build_header()
_build_summary_card()
_build_tabs()
_build_slot_machine_banner()
section_heading = Label.new()
section_heading.text = "Featured"
@@ -222,63 +217,6 @@ func _apply_tab_theme(dark: bool) -> void:
(entry["underline"] as ColorRect).color = Brand.ROYAL_BLUE if active else Color(0, 0, 0, 0)
func _build_slot_machine_banner() -> void:
var dark := UIThemeService.is_dark_mode()
banner_card = PanelContainer.new()
banner_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
add_child(banner_card)
var margin := MarginContainer.new()
margin.add_theme_constant_override("margin_left", 16)
margin.add_theme_constant_override("margin_right", 16)
margin.add_theme_constant_override("margin_top", 12)
margin.add_theme_constant_override("margin_bottom", 12)
banner_card.add_child(margin)
var row := HBoxContainer.new()
row.add_theme_constant_override("separation", 14)
margin.add_child(row)
banner_icon_panel = PanelContainer.new()
banner_icon_panel.custom_minimum_size = Vector2(40, 40)
banner_icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
banner_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 20))
var icon := TextureRect.new()
icon.texture = load("res://assets/icons/lucide/star.svg")
icon.custom_minimum_size = Vector2(20, 20)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.modulate = Brand.ROYAL_BLUE
banner_icon_panel.add_child(icon)
row.add_child(banner_icon_panel)
var copy := VBoxContainer.new()
copy.size_flags_horizontal = Control.SIZE_EXPAND_FILL
copy.size_flags_vertical = Control.SIZE_SHRINK_CENTER
copy.add_theme_constant_override("separation", 2)
banner_heading = Label.new()
banner_heading.text = "RZ Coin Slot Machine"
banner_heading.add_theme_font_override("font", Brand.font)
banner_heading.add_theme_font_size_override("font_size", 15)
banner_heading.add_theme_color_override("font_color", Brand.text_color(dark))
copy.add_child(banner_heading)
banner_description = Label.new()
banner_description.text = "Spend RZ Coins for a chance at bigger rewards."
banner_description.add_theme_font_override("font", Brand.font)
banner_description.add_theme_font_size_override("font_size", 12)
banner_description.add_theme_color_override("font_color", Brand.muted_color(dark))
copy.add_child(banner_description)
row.add_child(copy)
var play_button := Button.new()
play_button.text = "Play Now"
play_button.custom_minimum_size = Vector2(96, 36)
play_button.add_theme_font_override("font", Brand.font)
_style_buy_button(play_button)
play_button.pressed.connect(func(): main.show_screen("slot_machine"))
row.add_child(play_button)
func _build_footer() -> void:
var dark := UIThemeService.is_dark_mode()
footer_card = PanelContainer.new()
@@ -338,10 +276,6 @@ func _refresh_theme_controls() -> void:
coin_caption_label.add_theme_color_override("font_color", Brand.muted_color(dark))
inventory_label.add_theme_color_override("font_color", Brand.muted_color(dark))
_apply_tab_theme(dark)
banner_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
banner_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 20))
banner_heading.add_theme_color_override("font_color", Brand.text_color(dark))
banner_description.add_theme_color_override("font_color", Brand.muted_color(dark))
section_subtitle.add_theme_color_override("font_color", Brand.muted_color(dark))
footer_card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false))
footer_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 18))