diff --git a/assets/fonts/FiraMono-Regular.ttf b/assets/fonts/FiraMono-Regular.ttf
deleted file mode 100644
index 67bbd4287d424a70c582c86278bfa742a6bead6c..0000000000000000000000000000000000000000
Binary files a/assets/fonts/FiraMono-Regular.ttf and /dev/null differ
diff --git a/examples/login.rs b/examples/login.rs
index 29119703f6bcf676236b3915bd782dede7ec861d..f01f1e0da114115727ddd9d5102aff18bfdcee5c 100644
--- a/examples/login.rs
+++ b/examples/login.rs
@@ -1,8 +1,25 @@
-use bevy::{prelude::*, window::PrimaryWindow};
+use bevy::{
+    prelude::*,
+    window::{PrimaryWindow, WindowResolution},
+};
 use bevy_cosmic_edit::*;
 
-fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
-    let window = window.single();
+#[derive(Component)]
+struct SubmitButton;
+
+#[derive(Component)]
+struct UsernameTag;
+
+#[derive(Component)]
+struct PasswordTag;
+
+#[derive(Component)]
+struct DisplayTag;
+
+fn setup(mut commands: Commands, mut window: Query<&mut Window, With<PrimaryWindow>>) {
+    let mut window = window.single_mut();
+
+    window.resolution = WindowResolution::new(330.0, 480.0);
 
     commands.spawn(Camera2dBundle::default());
 
@@ -10,7 +27,10 @@ fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
         .spawn(NodeBundle {
             style: Style {
                 flex_direction: FlexDirection::Column,
-                width: Val::Px(300.0),
+                align_items: AlignItems::Center,
+                padding: UiRect::all(Val::Px(15.0)),
+                width: Val::Px(330.0),
+
                 ..default()
             },
             ..default()
@@ -40,7 +60,8 @@ fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
                 attrs: PlaceholderAttrs(AttrsOwned::new(
                     Attrs::new().color(bevy_color_to_cosmic(Color::rgb_u8(128, 128, 128))),
                 )),
-            });
+            })
+            .insert(UsernameTag);
 
             root.spawn(CosmicEditBundle {
                 max_lines: CosmicMaxLines(1),
@@ -62,42 +83,47 @@ fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
                 ..default()
             })
             .insert(CosmicEditPlaceholderBundle {
-                text_setter: PlaceholderText(CosmicText::OneStyle("Password ●".into())),
+                text_setter: PlaceholderText(CosmicText::OneStyle("Password".into())),
                 attrs: PlaceholderAttrs(AttrsOwned::new(
                     Attrs::new().color(bevy_color_to_cosmic(Color::rgb_u8(128, 128, 128))),
                 )),
             })
-            .insert(PasswordInput('●'));
+            .insert(PasswordTag)
+            .insert(PasswordInput::default());
 
             root.spawn(CosmicEditBundle {
                 max_lines: CosmicMaxLines(1),
                 metrics: CosmicMetrics {
+                    font_size: 25.0,
+                    line_height: 25.0,
                     scale_factor: window.scale_factor() as f32,
                     ..default()
                 },
+                attrs: CosmicAttrs(AttrsOwned::new(
+                    Attrs::new().color(bevy_color_to_cosmic(Color::WHITE)),
+                )),
+                text_setter: CosmicText::OneStyle("Submit".into()),
+                fill_color: FillColor(Color::GREEN),
                 ..default()
             })
             .insert(ButtonBundle {
                 style: Style {
                     // Size and position of text box
-                    width: Val::Px(300.),
+                    width: Val::Px(150.),
                     height: Val::Px(50.),
                     margin: UiRect::all(Val::Px(15.0)),
+                    border: UiRect::all(Val::Px(3.0)),
                     ..default()
                 },
                 background_color: BackgroundColor(Color::WHITE),
+                border_color: Color::DARK_GREEN.into(),
+
                 ..default()
             })
-            .insert(CosmicEditPlaceholderBundle {
-                text_setter: PlaceholderText(CosmicText::OneStyle("Password 🙊".into())),
-                attrs: PlaceholderAttrs(AttrsOwned::new(
-                    Attrs::new().color(bevy_color_to_cosmic(Color::rgb_u8(128, 128, 128))),
-                )),
-            })
-            .insert(PasswordInput('🙊'));
+            .insert(SubmitButton)
+            .insert(ReadOnly);
 
             root.spawn(CosmicEditBundle {
-                max_lines: CosmicMaxLines(1),
                 metrics: CosmicMetrics {
                     scale_factor: window.scale_factor() as f32,
                     ..default()
@@ -108,7 +134,7 @@ fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
                 style: Style {
                     // Size and position of text box
                     width: Val::Px(300.),
-                    height: Val::Px(50.),
+                    height: Val::Px(100.),
                     margin: UiRect::all(Val::Px(15.0)),
                     ..default()
                 },
@@ -116,12 +142,12 @@ fn setup(mut commands: Commands, window: Query<&Window, With<PrimaryWindow>>) {
                 ..default()
             })
             .insert(CosmicEditPlaceholderBundle {
-                text_setter: PlaceholderText(CosmicText::OneStyle("Password -".into())),
+                text_setter: PlaceholderText(CosmicText::OneStyle("Output".into())),
                 attrs: PlaceholderAttrs(AttrsOwned::new(
                     Attrs::new().color(bevy_color_to_cosmic(Color::rgb_u8(128, 128, 128))),
                 )),
             })
-            .insert(PasswordInput('-'));
+            .insert((ReadOnly, DisplayTag));
         });
 }
 
@@ -157,23 +183,59 @@ fn print_changed_input(mut evr_type: EventReader<CosmicTextChanged>) {
     }
 }
 
-fn main() {
-    let font_bytes: &[u8] = include_bytes!("../assets/fonts/FiraMono-Regular.ttf");
-    let font_config = CosmicFontConfig {
-        fonts_dir_path: None,
-        font_bytes: Some(vec![font_bytes]),
-        load_system_fonts: true,
-    };
+fn submit_button(
+    button_q: Query<&Interaction, With<SubmitButton>>,
+    username_q: Query<
+        &CosmicEditor,
+        (With<UsernameTag>, Without<PasswordTag>, Without<DisplayTag>),
+    >,
+    password_q: Query<
+        &CosmicEditor,
+        (With<PasswordTag>, Without<UsernameTag>, Without<DisplayTag>),
+    >,
+    mut display_q: Query<
+        (&mut CosmicEditor, &CosmicAttrs),
+        (With<DisplayTag>, Without<UsernameTag>, Without<PasswordTag>),
+    >,
+    mut font_system: ResMut<CosmicFontSystem>,
+    mut window: Query<&mut Window, With<PrimaryWindow>>,
+) {
+    for interaction in button_q.iter() {
+        match interaction {
+            Interaction::None => {}
+            Interaction::Pressed => {
+                let u = username_q.single();
+                let p = password_q.single();
+                let (mut d, attrs) = display_q.single_mut();
+
+                let text = format!(
+                    "Submitted!\nUsername: {}\nPassword: {}\n",
+                    u.get_text(),
+                    p.get_text()
+                );
 
+                d.set_text(
+                    CosmicText::OneStyle(text),
+                    attrs.0.clone(),
+                    &mut font_system.0,
+                );
+            }
+            Interaction::Hovered => {
+                window.single_mut().cursor.icon = CursorIcon::Hand;
+            }
+        }
+    }
+}
+
+fn main() {
     App::new()
         .add_plugins(DefaultPlugins)
         .add_plugins(CosmicEditPlugin {
             change_cursor: CursorConfig::Default,
-            font_config,
             ..default()
         })
         .add_systems(Startup, setup)
         .add_systems(Update, change_active_editor_ui)
-        .add_systems(Update, print_changed_input)
+        .add_systems(Update, (print_changed_input, submit_button))
         .run();
 }
diff --git a/src/lib.rs b/src/lib.rs
index e356ba627ee31c906d214cf7ef52776d9dafba6f..f74b71da8801f7da17865334a8b91e20bb3ab720 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,7 +22,7 @@ use input::{poll_wasm_paste, WasmPaste, WasmPasteAsyncChannel};
 use render::{
     blink_cursor, cosmic_edit_redraw_buffer, freeze_cursor_blink, hide_inactive_or_readonly_cursor,
     hide_password_text, on_scale_factor_change, restore_password_text, set_initial_scale,
-    CursorBlinkTimer, CursorVisibility, PasswordStates, SwashCacheState,
+    CursorBlinkTimer, CursorVisibility, PasswordValues, SwashCacheState,
 };
 
 #[cfg(feature = "multicam")]
@@ -106,7 +106,7 @@ struct XOffset(Option<(f32, f32)>);
 pub struct CosmicEditor(pub Editor);
 
 impl CosmicEditor {
-    fn set_text(
+    pub fn set_text(
         &mut self,
         text: CosmicText,
         attrs: AttrsOwned,
@@ -341,7 +341,7 @@ impl Plugin for CosmicEditPlugin {
             ),
         )
         .init_resource::<Focus>()
-        .init_resource::<PasswordStates>()
+        .init_resource::<PasswordValues>()
         .insert_resource(CursorBlinkTimer(Timer::from_seconds(
             0.53,
             TimerMode::Repeating,
diff --git a/src/render.rs b/src/render.rs
index 4589d32efb5e0edfb7b9aea2e94dff41e9edbee7..dae6ee53066279c8cb4c747f8d725f8a5250c023 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -28,6 +28,9 @@ pub(crate) struct CursorBlinkTimer(pub Timer);
 #[derive(Resource)]
 pub(crate) struct CursorVisibility(pub bool);
 
+#[derive(Resource, Default)]
+pub(crate) struct PasswordValues(pub HashMap<Entity, (String, usize)>);
+
 pub(crate) fn cosmic_edit_redraw_buffer(
     windows: Query<&Window, With<PrimaryWindow>>,
     mut images: ResMut<Assets<Image>>,
@@ -413,7 +416,7 @@ pub(crate) fn hide_inactive_or_readonly_cursor(
             let editor = &mut editor.0;
             let mut cursor = editor.0.cursor();
             if cursor.color == Some(cosmic_text::Color::rgba(0, 0, 0, 0)) {
-                return;
+                continue;
             }
             cursor.color = Some(cosmic_text::Color::rgba(0, 0, 0, 0));
             editor.0.set_cursor(cursor);
@@ -425,7 +428,7 @@ pub(crate) fn hide_inactive_or_readonly_cursor(
         if active_editor.is_none() || e != active_editor.0.unwrap() {
             let mut cursor = editor.0.cursor();
             if cursor.color == Some(cosmic_text::Color::rgba(0, 0, 0, 0)) {
-                return;
+                continue;
             }
             cursor.color = Some(cosmic_text::Color::rgba(0, 0, 0, 0));
             editor.0.set_cursor(cursor);
@@ -499,13 +502,10 @@ pub(crate) fn update_handle_sprite(
     }
 }
 
-#[derive(Resource, Default)]
-pub(crate) struct PasswordStates(pub HashMap<Entity, (String, usize)>);
-
 pub(crate) fn hide_password_text(
     mut editor_q: Query<(Entity, &mut CosmicEditor, &CosmicAttrs, &PasswordInput)>,
     mut font_system: ResMut<CosmicFontSystem>,
-    mut password_input_states: ResMut<PasswordStates>,
+    mut password_input_states: ResMut<PasswordValues>,
     active_editor: Res<Focus>,
 ) {
     for (entity, mut cosmic_editor, attrs, password) in editor_q.iter_mut() {
@@ -562,11 +562,10 @@ pub(crate) fn hide_password_text(
 pub(crate) fn restore_password_text(
     mut editor_q: Query<(Entity, &mut CosmicEditor, &CosmicAttrs, &PasswordInput)>,
     mut font_system: ResMut<CosmicFontSystem>,
-    password_input_states: Res<PasswordStates>,
+    password_input_states: Res<PasswordValues>,
 ) {
     for (entity, mut cosmic_editor, attrs, password) in editor_q.iter_mut() {
         if let Some((text, _glyph_idx)) = password_input_states.0.get(&entity) {
-            // reset intercepted text
             if !text.is_empty() {
                 let char_len = password.0.len_utf8();