diff --git a/solitaire_engine/src/assets/hud_icon_svg.rs b/solitaire_engine/src/assets/hud_icon_svg.rs
new file mode 100644
index 0000000..b8a7e40
--- /dev/null
+++ b/solitaire_engine/src/assets/hud_icon_svg.rs
@@ -0,0 +1,130 @@
+//! SVG builders for the floating tab bar's action icons.
+//!
+//! The touch tab bar (`hud_plugin::tab_bar`) is icon-first, but the bundled
+//! FiraMono face has no icon glyphs (and the Geometric Shapes block U+25xx
+//! is missing on Android entirely), so the icons are authored here as tiny
+//! stroke-based SVGs and rasterised through the same `usvg`/`resvg` pipeline
+//! as the card themes (`assets::rasterize_svg`).
+//!
+//! Icons are drawn in **white** on a transparent background inside a
+//! 24-unit logical box; the spawn site tints them to the theme colour via
+//! `ImageNode::color` (a per-node multiply), so one texture serves every
+//! button state.
+
+use bevy::image::Image;
+use bevy::math::UVec2;
+
+use super::svg_loader::{SvgLoaderError, rasterize_svg};
+
+/// Rasterisation size for one tab-bar icon texture. Icons display at
+/// 24 logical px; 96 px texels keep them crisp at the Fold's 1.2 scale
+/// factor (and any future 3× phone) while staying trivially small.
+pub const HUD_ICON_TEXTURE_PX: u32 = 96;
+
+/// The five actions the floating touch tab bar can show.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum HudIcon {
+ /// Counter-clockwise "take back" arrow.
+ Undo,
+ /// Two offset card outlines — draw from the stock.
+ Draw,
+ /// Lightbulb — highlight a suggested move.
+ Hint,
+ /// Two vertical bars.
+ Pause,
+ /// Three-line hamburger — the floating menu button.
+ Menu,
+}
+
+impl HudIcon {
+ /// Build the icon's SVG document. All icons share one visual language:
+ /// 2-unit white strokes, round caps, transparent fill, 24-unit box.
+ pub fn svg(self) -> String {
+ let body = match self {
+ // Arrow head pointing left into a half-circle sweeping back
+ // over the top — the conventional undo mark.
+ HudIcon::Undo => concat!(
+ r##""##,
+ r##""##,
+ ),
+ // Back card peeks out behind the front card; the front card is
+ // drawn second so its stroke reads on top.
+ HudIcon::Draw => concat!(
+ r##""##,
+ r##""##,
+ ),
+ // Bulb dome with a flat lamp base beneath.
+ HudIcon::Hint => concat!(
+ r##""##,
+ r##""##,
+ ),
+ HudIcon::Pause => concat!(
+ r##""##,
+ r##""##,
+ ),
+ HudIcon::Menu => concat!(
+ r##""##,
+ r##""##,
+ r##""##,
+ ),
+ };
+ format!(
+ concat!(
+ r##""##,
+ ),
+ body = body
+ )
+ }
+
+ /// Rasterise this icon into a Bevy [`Image`] at
+ /// [`HUD_ICON_TEXTURE_PX`] square.
+ pub fn rasterize(self) -> Result {
+ rasterize_svg(
+ self.svg().as_bytes(),
+ UVec2::splat(HUD_ICON_TEXTURE_PX),
+ )
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ const ALL: [HudIcon; 5] = [
+ HudIcon::Undo,
+ HudIcon::Draw,
+ HudIcon::Hint,
+ HudIcon::Pause,
+ HudIcon::Menu,
+ ];
+
+ /// Every icon must survive the real usvg/resvg pipeline at the real
+ /// texture size — a malformed path here would otherwise only surface
+ /// as a blank button on device.
+ #[test]
+ fn every_icon_rasterizes_at_texture_size() {
+ for icon in ALL {
+ let img = icon.rasterize().expect("icon SVG must rasterise");
+ assert_eq!(img.width(), HUD_ICON_TEXTURE_PX, "{icon:?} width");
+ assert_eq!(img.height(), HUD_ICON_TEXTURE_PX, "{icon:?} height");
+ }
+ }
+
+ /// Rasterised icons must contain visible (non-transparent) pixels —
+ /// guards against a stroke accidentally drawn outside the viewBox.
+ #[test]
+ fn every_icon_has_visible_pixels() {
+ for icon in ALL {
+ let img = icon.rasterize().expect("icon SVG must rasterise");
+ let data = img.data.as_ref().expect("rasterised image has data");
+ let opaque = data.chunks_exact(4).filter(|px| px[3] > 0).count();
+ assert!(
+ opaque > 100,
+ "{icon:?} renders only {opaque} visible pixels"
+ );
+ }
+ }
+}
diff --git a/solitaire_engine/src/assets/mod.rs b/solitaire_engine/src/assets/mod.rs
index 7b11934..21d946a 100644
--- a/solitaire_engine/src/assets/mod.rs
+++ b/solitaire_engine/src/assets/mod.rs
@@ -5,6 +5,7 @@
//! custom `AssetSource` implementations used by the theme system.
pub mod card_face_svg;
+pub mod hud_icon_svg;
pub mod icon_svg;
pub mod sources;
pub mod svg_loader;