diff --git a/Cargo.lock b/Cargo.lock
index 9d8b10d08a172343ac0ea5d514c83ae3b3b8828e..75d99775f0bba64b5c0dcaea409db9bf0297100f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,18 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e"
 
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "adler32"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
+
 [[package]]
 name = "ahash"
 version = "0.4.7"
@@ -294,6 +306,12 @@ dependencies = [
  "objc",
 ]
 
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
 [[package]]
 name = "combine"
 version = "4.6.4"
@@ -409,6 +427,15 @@ dependencies = [
  "objc",
 ]
 
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
 [[package]]
 name = "cty"
 version = "0.2.2"
@@ -473,6 +500,15 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b"
 
+[[package]]
+name = "deflate"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f"
+dependencies = [
+ "adler32",
+]
+
 [[package]]
 name = "derivative"
 version = "2.2.0"
@@ -781,6 +817,8 @@ name = "generative_art_cartoon"
 version = "0.1.0"
 dependencies = [
  "eframe",
+ "image",
+ "rand",
 ]
 
 [[package]]
@@ -921,6 +959,21 @@ dependencies = [
  "unicode-normalization",
 ]
 
+[[package]]
+name = "image"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "num-iter",
+ "num-rational",
+ "num-traits",
+ "png",
+]
+
 [[package]]
 name = "instant"
 version = "0.1.12"
@@ -1060,6 +1113,15 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
+[[package]]
+name = "miniz_oxide"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
+dependencies = [
+ "adler",
+]
+
 [[package]]
 name = "mio"
 version = "0.8.2"
@@ -1224,6 +1286,47 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "num-integer"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "num_enum"
 version = "0.5.7"
@@ -1373,6 +1476,18 @@ version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
 
+[[package]]
+name = "png"
+version = "0.17.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "deflate",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "polling"
 version = "2.2.0"
diff --git a/Cargo.toml b/Cargo.toml
index a6cc859ecb58627f9986a7f3b89e17628de26463..1430cd253fc10340e166e6f51090526bd5826923 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,4 +4,6 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-eframe = "0.17"
\ No newline at end of file
+eframe = "0.17"
+image = {version = "0.24", default-features = false, features=["png"]}
+rand = {version = "0.8"}
\ No newline at end of file
diff --git a/src/image.rs b/src/image.rs
new file mode 100644
index 0000000000000000000000000000000000000000..494bea17036d84dcba552dbbaa5dd1459cf07b85
--- /dev/null
+++ b/src/image.rs
@@ -0,0 +1,31 @@
+#[macro_export]
+macro_rules! img {
+    ($name: literal) => {{
+        crate::image::load_image_from_memory(include_bytes!(concat!(
+            env!("CARGO_MANIFEST_DIR"),
+            "/src/image/",
+            $name
+        )))
+        .expect($name)
+    }};
+}
+
+#[macro_export]
+macro_rules! ctx_img {
+    ($ctx: expr, $name: literal) => {{
+        $ctx.load_texture($name, img!($name))
+    }};
+}
+
+pub fn load_image_from_memory(
+    image_data: &[u8],
+) -> Result<eframe::egui::ColorImage, image::ImageError> {
+    let image = image::load_from_memory(image_data)?;
+    let size = [image.width() as _, image.height() as _];
+    let image_buffer = image.to_rgba8();
+    let pixels = image_buffer.as_flat_samples();
+    Ok(eframe::egui::ColorImage::from_rgba_unmultiplied(
+        size,
+        pixels.as_slice(),
+    ))
+}
diff --git a/src/image/atom0.png b/src/image/atom0.png
new file mode 100644
index 0000000000000000000000000000000000000000..c37eb0a032396e9b71d9ff7e8c68245c3cb739b4
Binary files /dev/null and b/src/image/atom0.png differ
diff --git a/src/image/atom1.png b/src/image/atom1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6625537825c8f5ed07420e19171c49a0519f020
Binary files /dev/null and b/src/image/atom1.png differ
diff --git a/src/image/atom2.png b/src/image/atom2.png
new file mode 100644
index 0000000000000000000000000000000000000000..19640b815dbc37c9b34f3e9bb9ffaae87344e57c
Binary files /dev/null and b/src/image/atom2.png differ
diff --git a/src/image/raymarching0.png b/src/image/raymarching0.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5684a18bbf877fbebcb6e599f15879f3afe5b6b
Binary files /dev/null and b/src/image/raymarching0.png differ
diff --git a/src/image/raymarching1.png b/src/image/raymarching1.png
new file mode 100644
index 0000000000000000000000000000000000000000..c97d83ad36d5f953c214780eef0ed50c585e75dd
Binary files /dev/null and b/src/image/raymarching1.png differ
diff --git a/src/main.rs b/src/main.rs
index e8b8ded8e99aa4d98c702a1d17e7755768adf8fb..ef95780ebfbd00a32a84199b3cd9411e0e06c96f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,22 @@
+pub mod image;
+pub mod slide;
+
+use crate::slide::title::Title;
+use crate::slide::Slide;
+use eframe::egui::style::Widgets;
+use eframe::egui::{
+    Align, Direction, FontFamily, Layout, Pos2, Rect, Style, TextStyle, Vec2, Visuals,
+};
+use eframe::epi::{Frame, Storage};
 use eframe::{egui, epi};
-use eframe::egui::{Align, Direction, Layout};
+use std::collections::VecDeque;
 
 fn main() {
     let app = Cartoon::default();
 
     let size = egui::Vec2::new(1280f32, 720f32);
 
-    let native_options = eframe::NativeOptions{
+    let native_options = eframe::NativeOptions {
         always_on_top: false,
         maximized: false,
         decorated: true,
@@ -24,12 +34,14 @@ fn main() {
 }
 
 pub struct Cartoon {
-
+    slides: VecDeque<Box<dyn Slide>>,
 }
 
 impl Default for Cartoon {
     fn default() -> Self {
-        Self {}
+        Self {
+            slides: vec![Box::new(Title::default()) as Box<dyn Slide>].into(),
+        }
     }
 }
 
@@ -38,6 +50,21 @@ impl epi::App for Cartoon {
         "Generative Art Cartoon"
     }
 
+    fn setup(&mut self, ctx: &egui::Context, _frame: &Frame, _storage: Option<&dyn Storage>) {
+        let mut style = Style::default();
+        style.animation_time = 0.5;
+        style.visuals = Visuals::light();
+        {
+            let header_style = style.text_styles.get_mut(&TextStyle::Heading).unwrap();
+            header_style.size = 48.0;
+        }
+        {
+            let body_style = style.text_styles.get_mut(&TextStyle::Body).unwrap();
+            body_style.size = 30.0;
+        }
+        ctx.set_style(style);
+    }
+
     /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
     fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
         // For inspiration and more examples, go to https://emilk.github.io/egui
@@ -54,13 +81,6 @@ impl epi::App for Cartoon {
         });
          */
 
-        egui::CentralPanel::default().show(ctx, |ui| {
-            ui.centered_and_justified(|ui| {
-                egui::CentralPanel::default().show_inside(ui, |ui| {
-                    ui.heading("Generative Art");
-                    ui.label("By TODO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
-                });
-            });
-        });
+        self.slides[0].update(ctx, frame);
     }
-}
\ No newline at end of file
+}
diff --git a/src/slide.rs b/src/slide.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4fc6b1378edc44f75c0f9abb91dc1dbeb499fdb6
--- /dev/null
+++ b/src/slide.rs
@@ -0,0 +1,7 @@
+use eframe::{egui, epi};
+
+pub mod title;
+
+pub trait Slide {
+    fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame);
+}
diff --git a/src/slide/title.rs b/src/slide/title.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ab6f2dbfbfb4e1e7ef1fb3f180bb26789e32104d
--- /dev/null
+++ b/src/slide/title.rs
@@ -0,0 +1,47 @@
+use crate::egui::{Align2, Context};
+use crate::epi::Frame;
+use crate::{ctx_img, img, Slide};
+use eframe::egui;
+use eframe::egui::{Align, Layout, ScrollArea, Vec2, Window};
+use rand::Rng;
+
+#[derive(Default)]
+pub struct Title {
+    examples: Vec<egui::TextureHandle>,
+}
+
+impl Slide for Title {
+    fn update(&mut self, ctx: &Context, _frame: &Frame) {
+        if self.examples.is_empty() {
+            self.examples = vec![
+                ctx_img!(ctx, "raymarching0.png"),
+                ctx_img!(ctx, "raymarching1.png"),
+                ctx_img!(ctx, "atom0.png"),
+                ctx_img!(ctx, "atom1.png"),
+                ctx_img!(ctx, "atom2.png"),
+            ];
+        }
+
+        egui::CentralPanel::default().show(ctx, |ui| {
+            for example in &self.examples {
+                Window::new(example.name())
+                    .title_bar(false)
+                    .resizable(false)
+                    .show(ctx, |ui| {
+                        ui.image(example, Vec2::splat(128.0));
+                    });
+            }
+
+            Window::new("title")
+                .title_bar(false)
+                .resizable(false)
+                .anchor(Align2::CENTER_CENTER, Vec2::ZERO)
+                .show(ctx, |ui| {
+                    ui.vertical_centered(|ui| {
+                        ui.heading("Generative Art");
+                        ui.label("By: TODO");
+                    });
+                });
+        });
+    }
+}