}
 
 pub fn top_controls<'a>(is_playing: bool) -> Element<'a, Message> {
-    let play_button =
-        button(if is_playing { "pause" } else { "play" }).on_press(Message::TogglePlayback);
+    let play_button = row![
+        button(if is_playing { "stop" } else { "play" }).on_press(Message::TogglePlayback),
+        button("save")
+            .on_press(Message::Save)
+            .style(theme::Button::Positive),
+        button("clear")
+            .on_press(Message::Clear)
+            .style(theme::Button::Destructive),
+    ]
+    .width(Length::Fill)
+    .spacing(10);
 
     let other_controls = row![button("quit")
         .on_press(Message::Quit)
         .style(theme::Button::Destructive),]
     .width(Length::Fill)
-    .align_items(Alignment::End)
     .spacing(10);
 
     row![play_button, other_controls]
 }
 
 pub fn bottom_controls<'a>(message: ControlMessage) -> Element<'a, Message> {
-    column![map_section(&message), midi_section(&message),]
-        .width(Length::Fill)
-        .height(Length::Fill)
-        .padding(10)
-        .spacing(20)
-        .align_items(Alignment::Center)
-        .into()
+    column![
+        map_section(&message),
+        probability_section(message.info.probability).width(Length::Fixed(600.0)),
+        midi_section(&message),
+    ]
+    .width(Length::Fill)
+    .height(Length::Fill)
+    .padding(10)
+    .spacing(20)
+    .align_items(Alignment::Center)
+    .into()
 }
 
 fn map_section<'a>(message: &ControlMessage) -> Row<'a, Message> {
     row![
         map_buttons(),
-        column![
-            probability_section(message.info.probability),
-            randomize_section(message.randomness)
-        ]
-        .padding(10)
-        .spacing(10)
-        .align_items(Alignment::Center)
+        randomize_section(message.randomness).width(Length::Fixed(500.0))
     ]
     .spacing(10)
 }
 
 fn probability_section<'a>(p: f32) -> Row<'a, Message> {
     row![
+        text("probability a cell gets triggered")
+            .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))),
         slider(0.0..=100.0, p * 100.0, |x| {
             Message::ProbChanged(x / 100.0)
         }),
         text(format!("{p}")),
-        text("probability a cell gets triggered")
-            .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40)))
     ]
     .spacing(10)
 }
 
 fn randomize_section<'a>(r: f32) -> Row<'a, Message> {
     row![
+        text("percent of board to fill on randomize")
+            .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))),
         slider(0.0..=100.0, r * 100.0, |x| {
             Message::RandChanged(x / 100.0)
         }),
         text(format!("{r}")),
-        text("percent of board to fill on randomize")
-            .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40)))
     ]
     .spacing(10)
 }
 
 fn map_buttons<'a>() -> Column<'a, Message> {
-    column![
-        row![
-            button("save")
-                .on_press(Message::Save)
-                .style(theme::Button::Positive),
-            button("clear")
-                .on_press(Message::Clear)
-                .style(theme::Button::Destructive),
-        ]
-        .spacing(10),
-        row![
-            button("reset")
-                .on_press(Message::Reset)
-                .style(theme::Button::Secondary),
-            button("random")
-                .on_press(Message::Randomize)
-                .style(theme::Button::Primary),
-        ]
-        .spacing(10)
+    column![row![
+        button("reset")
+            .on_press(Message::Reset)
+            .style(theme::Button::Secondary),
+        button("random")
+            .on_press(Message::Randomize)
+            .style(theme::Button::Primary),
     ]
+    .spacing(10)]
     .spacing(10)
 }
 
 fn velocity_sliders<'a>(min: u8, max: u8) -> Column<'a, Message> {
     column![
         row![
-            text(format!("{max}")),
-            slider(0..=127, max, Message::NewVMax),
             text("maximum velocity")
-                .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40)))
+                .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))),
+            slider(0..=127, max, Message::NewVMax),
+            text(format!("{max}")),
         ]
         .spacing(10),
         row![
-            text(format!("{min}")),
-            slider(0..=127, min, Message::NewVMin),
             text("minimum velocity")
-                .style(theme::Text::Color(iced::Color::from_rgb8(0x40, 0x40, 0x40)))
+                .style(theme::Text::Color(iced::Color::from_rgb8(0x60, 0x60, 0x60))),
+            slider(0..=127, min, Message::NewVMin),
+            text(format!("{min}")),
         ]
         .spacing(10),
     ]
     column![
         song_section(message),
         velocity_sliders(message.info.velocity.min(), message.info.velocity.max())
+            .width(Length::Fixed(500.0))
     ]
     .spacing(10)
 }
     row![
         pick_list(&RootNote::ALL[..], Some(note), move |note| {
             Message::NewNote(Root::new(note, acc))
-        }),
+        })
+        .width(Length::Fixed(50.0)),
         pick_list(&Accidental::ALL[..], Some(acc), move |acc| {
             Message::NewNote(Root::new(note, acc))
-        }),
-        pick_list(&Scale::ALL[..], Some(scale), Message::Scale),
+        })
+        .width(Length::Fixed(90.0)),
+        pick_list(&Scale::ALL[..], Some(scale), Message::Scale).width(Length::Fixed(160.0)),
     ]
     .align_items(Alignment::Center)
 }
 
     theme::Theme,
     time,
     widget::{column, container, row},
-    {Alignment, Application, Command, Element, Length, Point, Subscription},
+    window, {Alignment, Application, Command, Element, Length, Point, Subscription},
 };
 
 use itertools::Itertools;
         Self {
             is_playing: false,
             bpm: 120,
-            divisor: 1,
+            divisor: 4,
             is_looping: false,
             loop_len: 16,
             step_num: 0,
 
     fn update(&mut self, message: Message) -> Command<Message> {
         match message {
-            Message::Quit => todo!(), // TODO: figure out how to cleanly quit
             Message::None => {}
             Message::MapMessage(message) => self.map.update(message),
             Message::MaskMessage(message) => self.mask.update(message),
             Message::OctaveRange(r) => self.info.octave.set_range(r),
             Message::NewNote(r) => self.info.root = r,
             Message::Voices(v) => self.info.voices = v,
+            Message::Quit => return window::close(),
         }
 
         Command::none()
     fn subscription(&self) -> Subscription<Message> {
         if self.song.is_playing {
             time::every(Duration::from_millis(
-                60000 / (self.song.bpm * self.song.divisor) as u64,
+                240000 / (self.song.bpm * self.song.divisor) as u64,
             ))
             .map(Message::Tick)
         } else {
             self.mask.view().map(Message::MaskMessage)
         ]
         .align_items(Alignment::Center)
-        .width(Length::Fill)
         .spacing(40)
-        .padding(20);
+        .padding(40);
 
         let bottom = bottom_controls(self.control_message());
 
-        let content = column![top, map, bottom];
+        let content = column![top, map, bottom].width(Length::Fill);
 
         container(content)
             .width(Length::Fill)