diff --git a/app/assets/javascripts/wizard/components/scheme-preview.js.es6 b/app/assets/javascripts/wizard/components/scheme-preview.js.es6
new file mode 100644
index 000000000..484dafab5
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/scheme-preview.js.es6
@@ -0,0 +1,199 @@
+/*eslint no-bitwise:0 */
+
+import { observes } from 'ember-addons/ember-computed-decorators';
+
+const WIDTH  = 400;
+const HEIGHT = 220;
+const LINE_HEIGHT = 12.0;
+
+const LOREM = `
+Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+Nullam eget sem non elit tincidunt rhoncus. Fusce velit nisl,
+porttitor sed nisl ac, consectetur interdum metus. Fusce in
+consequat augue, vel facilisis felis. Nunc tellus elit, and
+semper vitae orci nec, blandit pharetra enim. Aenean a ebus
+posuere nunc. Maecenas ultrices viverra enim ac commodo
+Vestibulum nec quam sit amet libero ultricies sollicitudin.
+Nulla quis scelerisque sem, eget volutpat velit. Fusce eget
+accumsan sapien, nec feugiat quam. Quisque non risus.
+placerat lacus vitae, lacinia nisi. Sed metus arcu, iaculis
+sit amet cursus nec, sodales at eros.`;
+
+function loadImage(src) {
+  const img = new Image();
+  img.src = src;
+
+  return new Ember.RSVP.Promise(resolve => img.onload = () => resolve(img));
+};
+
+function parseColor(color) {
+  const m = color.match(/^#([0-9a-f]{6})$/i);
+  if (m) {
+    const c = m[1];
+    return [ parseInt(c.substr(0,2),16), parseInt(c.substr(2,2),16), parseInt(c.substr(4,2),16) ];
+  }
+
+  return [0, 0, 0];
+}
+
+function brightness(color) {
+  return (color[0] * 0.299) + (color[1] * 0.587) + (color[2] * 0.114);
+}
+
+function lighten(color, percent) {
+  return '#' +
+    ((0|(1<<8) + color[0] + (256 - color[0]) * percent / 100).toString(16)).substr(1) +
+    ((0|(1<<8) + color[1] + (256 - color[1]) * percent / 100).toString(16)).substr(1) +
+    ((0|(1<<8) + color[2] + (256 - color[2]) * percent / 100).toString(16)).substr(1);
+}
+
+function chooseBrighter(primary, secondary) {
+  const primaryCol = parseColor(primary);
+  const secondaryCol = parseColor(secondary);
+
+  return brightness(primaryCol) < brightness(secondaryCol) ? secondary : primary;
+}
+
+function darkLightDiff(adjusted, comparison, lightness, darkness) {
+  const adjustedCol = parseColor(adjusted);
+  const comparisonCol = parseColor(comparison);
+  return lighten(adjustedCol, (brightness(adjustedCol) < brightness(comparisonCol)) ?
+                               lightness : darkness);
+}
+
+export default Ember.Component.extend({
+  ctx: null,
+  width: WIDTH,
+  height: HEIGHT,
+  loaded: false,
+  logo: null,
+
+  colorScheme: Ember.computed.alias('step.fieldsById.color_scheme.value'),
+
+  didInsertElement() {
+    this._super();
+    const c = this.$('canvas')[0];
+    this.ctx = c.getContext("2d");
+
+    Ember.RSVP.Promise.all([loadImage('/images/wizard/discourse-small.png'),
+                            loadImage('/images/wizard/trout.png')]).then(result => {
+      this.logo = result[0];
+      this.avatar = result[1];
+      this.loaded = true;
+      this.triggerRepaint();
+    });
+  },
+
+  @observes('colorScheme')
+  triggerRepaint() {
+    Ember.run.scheduleOnce('afterRender', this, 'repaint');
+  },
+
+  repaint() {
+    if (!this.loaded) { return; }
+
+    const { ctx } = this;
+    const headerHeight = HEIGHT * 0.15;
+
+    const colorScheme = this.get('colorScheme');
+    const options = this.get('step.fieldsById.color_scheme.options');
+    const option = options.findProperty('id', colorScheme);
+    if (!option) { return; }
+
+    const colors = option.data.colors;
+    if (!colors) { return; }
+
+    ctx.fillStyle = colors.secondary;
+    ctx.fillRect(0, 0, WIDTH, HEIGHT);
+
+    // Header area
+    ctx.save();
+    ctx.beginPath();
+    ctx.rect(0, 0, WIDTH, headerHeight);
+    ctx.fillStyle = colors.header_background;
+    ctx.shadowColor = "rgba(0, 0, 0, 0.25)";
+    ctx.shadowBlur = 2;
+    ctx.shadowOffsetX = 0;
+    ctx.shadowOffsetY = 2;
+    ctx.fill();
+    ctx.restore();
+
+    const margin = WIDTH * 0.02;
+    const avatarSize = HEIGHT * 0.1;
+
+    // Logo
+    const headerMargin = headerHeight * 0.2;
+    const logoHeight = headerHeight - (headerMargin * 2);
+    const logoWidth = (logoHeight / this.logo.height) * this.logo.width;
+    ctx.drawImage(this.logo, headerMargin, headerMargin, logoWidth, logoHeight);
+
+    // Top right menu
+    ctx.drawImage(this.avatar, WIDTH - avatarSize - headerMargin, headerMargin, avatarSize, avatarSize);
+    ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 45, 55);
+    ctx.font = "0.75em FontAwesome";
+    ctx.fillText("\uf0c9", WIDTH - (avatarSize * 2) - (headerMargin * 0.5), avatarSize);
+    ctx.fillText("\uf002", WIDTH - (avatarSize * 3) - (headerMargin * 0.5), avatarSize);
+
+    // Draw a fake topic
+    ctx.drawImage(this.avatar, margin, headerHeight + (HEIGHT * 0.17), avatarSize, avatarSize);
+
+    ctx.beginPath();
+    ctx.fillStyle = colors.primary;
+    ctx.font = "bold 0.75em 'Arial'";
+    ctx.fillText("Welcome to Discourse", margin, (HEIGHT * 0.25));
+
+    ctx.font = "0.5em 'Arial'";
+
+    let line = 0;
+
+    const lines = LOREM.split("\n");
+    for (let i=0; i<10; i++) {
+      line = (HEIGHT * 0.3) + (i * LINE_HEIGHT);
+      ctx.fillText(lines[i], margin + avatarSize + margin, line);
+    }
+
+    // Reply Button
+    ctx.beginPath();
+    ctx.rect(WIDTH * 0.57, line + LINE_HEIGHT, WIDTH * 0.1, HEIGHT * 0.07);
+    ctx.fillStyle = colors.tertiary;
+    ctx.fill();
+    ctx.fillStyle = chooseBrighter(colors.primary, colors.secondary);
+    ctx.font = "8px 'Arial'";
+    ctx.fillText("Reply", WIDTH * 0.595, line + (LINE_HEIGHT * 1.8));
+
+    // Icons
+    ctx.font = "0.5em FontAwesome";
+    ctx.fillStyle = colors.love;
+    ctx.fillText("\uf004", WIDTH * 0.48, line + (LINE_HEIGHT * 1.8));
+    ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 65, 55);
+    ctx.fillText("\uf040", WIDTH * 0.525, line + (LINE_HEIGHT * 1.8));
+
+    // Draw Timeline
+    const timelineX = WIDTH * 0.8;
+    ctx.beginPath();
+    ctx.strokeStyle = colors.tertiary;
+    ctx.lineWidth = 0.5;
+    ctx.moveTo(timelineX, HEIGHT * 0.3);
+    ctx.lineTo(timelineX, HEIGHT * 0.6);
+    ctx.stroke();
+
+    // Timeline
+    ctx.beginPath();
+    ctx.strokeStyle = colors.tertiary;
+    ctx.lineWidth = 2;
+    ctx.moveTo(timelineX, HEIGHT * 0.3);
+    ctx.lineTo(timelineX, HEIGHT * 0.4);
+    ctx.stroke();
+
+    ctx.font = "Bold 0.5em Arial";
+    ctx.fillStyle = colors.primary;
+    ctx.fillText("1 / 20", timelineX + margin, (HEIGHT * 0.3) + (margin * 1.5));
+
+    // draw border
+    ctx.beginPath();
+    ctx.strokeStyle='rgba(0, 0, 0, 0.2)';
+    ctx.rect(0, 0, WIDTH, HEIGHT);
+    ctx.stroke();
+  }
+
+});
diff --git a/app/assets/javascripts/wizard/components/wizard-field.js.es6 b/app/assets/javascripts/wizard/components/wizard-field.js.es6
index cb4c67de9..67b65ee47 100644
--- a/app/assets/javascripts/wizard/components/wizard-field.js.es6
+++ b/app/assets/javascripts/wizard/components/wizard-field.js.es6
@@ -6,6 +6,9 @@ export default Ember.Component.extend({
   @computed('field.id')
   inputClassName: id => `field-${Ember.String.dasherize(id)}`,
 
-  @computed('field.type')
-  inputComponentName: type => `wizard-field-${type}`
+  @computed('field.type', 'field.id')
+  inputComponentName(type, id) {
+    return (type === 'component') ? Ember.String.dasherize(id) : `wizard-field-${type}`;
+  }
+
 });
diff --git a/app/assets/javascripts/wizard/models/step.js.es6 b/app/assets/javascripts/wizard/models/step.js.es6
index 5fa3b61be..a2ba11408 100644
--- a/app/assets/javascripts/wizard/models/step.js.es6
+++ b/app/assets/javascripts/wizard/models/step.js.es6
@@ -8,6 +8,13 @@ export default Ember.Object.extend(ValidState, {
   @computed('index')
   displayIndex: index => index + 1,
 
+  @computed('fields.[]')
+  fieldsById(fields) {
+    const lookup = {};
+    fields.forEach(field => lookup[field.get('id')] = field);
+    return lookup;
+  },
+
   checkFields() {
     let allValid = true;
     this.get('fields').forEach(field => {
diff --git a/app/assets/javascripts/wizard/templates/components/scheme-preview.hbs b/app/assets/javascripts/wizard/templates/components/scheme-preview.hbs
new file mode 100644
index 000000000..a4950856a
--- /dev/null
+++ b/app/assets/javascripts/wizard/templates/components/scheme-preview.hbs
@@ -0,0 +1,4 @@
+<div class='preview-area'>
+  <canvas width={{width}} height={{height}}>
+  </canvas>
+</div>
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
index 8339c5269..4f843aa3e 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
@@ -1 +1 @@
-{{combo-box value=field.value content=field.options nameProperty="label" width="400px"}}
+{{combo-box class=inputClassName value=field.value content=field.options nameProperty="label" width="400px"}}
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
index d757791f8..973630851 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
@@ -2,7 +2,7 @@
   <span class='label-value'>{{field.label}}</span>
 
   <div class='input-area'>
-    {{component inputComponentName field=field inputClassName=inputClassName}}
+    {{component inputComponentName field=field step=step inputClassName=inputClassName}}
   </div>
 
   {{#if field.errorDescription}}
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-step.hbs b/app/assets/javascripts/wizard/templates/components/wizard-step.hbs
index ff6a90120..52d174d06 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-step.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-step.hbs
@@ -8,7 +8,7 @@
 
 {{#wizard-step-form step=step}}
   {{#each step.fields as |field|}}
-    {{wizard-field field=field}}
+    {{wizard-field field=field step=step}}
   {{/each}}
 {{/wizard-step-form}}
 
diff --git a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
index 345f61356..af59f65dd 100644
--- a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
+++ b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
@@ -8,7 +8,7 @@ test("Wizard starts", assert => {
   });
 });
 
-test("Forum Name Step", assert => {
+test("Going back and forth in steps", assert => {
   visit("/step/hello-world");
   andThen(() => {
     assert.ok(exists('.wizard-step'));
@@ -44,7 +44,10 @@ test("Forum Name Step", assert => {
     assert.ok(!exists('.wizard-field .field-error-description'));
     assert.ok(!exists('.wizard-step-title'));
     assert.ok(!exists('.wizard-step-description'));
-    assert.ok(exists('input.field-email'), "went to the next step");
+
+    assert.ok(exists('select.field-snack'), "went to the next step");
+    assert.ok(exists('.preview-area'), "renders the component field");
+
     assert.ok(!exists('.wizard-btn.next'));
     assert.ok(exists('.wizard-btn.done'), 'last step shows a done button');
     assert.ok(exists('.wizard-btn.back'), 'shows the back button');
diff --git a/app/assets/javascripts/wizard/test/test_helper.js b/app/assets/javascripts/wizard/test/test_helper.js
index 17f51e38b..caf53122b 100644
--- a/app/assets/javascripts/wizard/test/test_helper.js
+++ b/app/assets/javascripts/wizard/test/test_helper.js
@@ -10,6 +10,7 @@
 //= require ember-qunit
 //= require ember-shim
 //= require wizard-application
+//= require wizard-vendor
 //= require helpers/assertions
 //= require_tree ./acceptance
 //= require_tree ./models
diff --git a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6 b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
index 6e0808fc6..546f61fd7 100644
--- a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
+++ b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
@@ -49,7 +49,10 @@ export default function() {
           {
             id: 'second-step',
             index: 1,
-            fields: [{ id: 'email', type: 'text', required: true }],
+            fields: [
+              { id: 'snack', type: 'dropdown', required: true },
+              { id: 'scheme-preview', type: 'component' }
+            ],
             previous: 'hello-world'
           }]
         }
diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss
index dfffa573b..cfb048e5b 100644
--- a/app/assets/stylesheets/wizard.scss
+++ b/app/assets/stylesheets/wizard.scss
@@ -16,6 +16,9 @@ body.wizard {
 .select {
   width: 400px;
 }
+.select2-results .select2-highlighted {
+  background: #ff9;
+}
 
 .wizard-column {
   background-color: white;
diff --git a/app/models/color_scheme.rb b/app/models/color_scheme.rb
index 0c1867f45..11c022583 100644
--- a/app/models/color_scheme.rb
+++ b/app/models/color_scheme.rb
@@ -3,6 +3,32 @@ require_dependency 'distributed_cache'
 
 class ColorScheme < ActiveRecord::Base
 
+  def self.themes
+    base_with_hash = {}
+    base_colors.each do |name, color|
+      base_with_hash[name] = "##{color}"
+    end
+
+    [
+      { id: 'default', colors: base_with_hash },
+      {
+        id: 'dark',
+        colors: {
+          "primary" =>           '#dddddd',
+          "secondary" =>         '#222222',
+          "tertiary" =>          '#0f82af',
+          "quaternary" =>        '#c14924',
+          "header_background" => '#111111',
+          "header_primary" =>    '#333333',
+          "highlight" =>         '#a87137',
+          "danger" =>            '#e45735',
+          "success" =>           '#1ca551',
+          "love" =>              '#fa6c8d'
+        }
+      }
+    ]
+  end
+
   def self.hex_cache
     @hex_cache ||= DistributedCache.new("scheme_hex_for_name")
   end
@@ -30,7 +56,7 @@ class ColorScheme < ActiveRecord::Base
     @mutex.synchronize do
       return @base_colors if @base_colors
       @base_colors = {}
-      read_colors_file.each do |line|
+      File.readlines(BASE_COLORS_FILE).each do |line|
         matches = /\$([\w]+):\s*#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})(?:[;]|\s)/.match(line.strip)
         @base_colors[matches[1]] = matches[2] if matches
       end
@@ -38,10 +64,6 @@ class ColorScheme < ActiveRecord::Base
     @base_colors
   end
 
-  def self.read_colors_file
-    File.readlines(BASE_COLORS_FILE)
-  end
-
   def self.enabled
     current_version.find_by(enabled: true)
   end
@@ -114,7 +136,6 @@ class ColorScheme < ActiveRecord::Base
     DiscourseStylesheets.cache.clear
   end
 
-
   def dump_hex_cache
     self.class.hex_cache.clear
   end
diff --git a/app/serializers/wizard_field_serializer.rb b/app/serializers/wizard_field_serializer.rb
index 07babfed0..7f69605ee 100644
--- a/app/serializers/wizard_field_serializer.rb
+++ b/app/serializers/wizard_field_serializer.rb
@@ -52,7 +52,17 @@ class WizardFieldSerializer < ApplicationSerializer
 
   def options
     object.options.map do |o|
-      {id: o, label: I18n.t("#{i18n_key}.options.#{o}")}
+
+      result = {id: o, label: I18n.t("#{i18n_key}.options.#{o}")}
+
+      data = object.option_data[o]
+      if data.present?
+        as_json = data.dup
+        as_json.delete(:id)
+        result[:data] = as_json
+      end
+
+      result
     end
   end
 
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 3548ce278..c3be14d8a 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -3247,8 +3247,8 @@ en:
           color_scheme:
             label: "Color Scheme"
             options:
-              default: "Default Scheme"
-              dark: "Dark Scheme"
+              default: "Simple"
+              dark: "Dark"
 
       finished:
         title: "Your Discourse Forum is Ready!"
diff --git a/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb b/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb
new file mode 100644
index 000000000..40c69d416
--- /dev/null
+++ b/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb
@@ -0,0 +1,5 @@
+class AddViaWizardToColorSchemes < ActiveRecord::Migration
+  def change
+    add_column :color_schemes, :via_wizard, :boolean, default: false, null: false
+  end
+end
diff --git a/lib/wizard.rb b/lib/wizard.rb
index a700f2457..7e8d46a00 100644
--- a/lib/wizard.rb
+++ b/lib/wizard.rb
@@ -44,8 +44,9 @@ class Wizard
 
     theme = wizard.create_step('colors')
     scheme = theme.add_field(id: 'color_scheme', type: 'dropdown', required: true)
-    scheme.add_option('default')
-    scheme.add_option('dark')
+    ColorScheme.themes.each {|t| scheme.add_option(t[:id], t) }
+
+    theme.add_field(id: 'scheme_preview', type: 'component')
     wizard.append_step(theme)
 
     finished = wizard.create_step('finished')
diff --git a/lib/wizard/field.rb b/lib/wizard/field.rb
index 83b6763bd..70afc2df8 100644
--- a/lib/wizard/field.rb
+++ b/lib/wizard/field.rb
@@ -1,7 +1,7 @@
 class Wizard
   class Field
 
-    attr_reader :id, :type, :required, :value, :options
+    attr_reader :id, :type, :required, :value, :options, :option_data
     attr_accessor :step
 
     def initialize(attrs)
@@ -12,10 +12,12 @@ class Wizard
       @required = !!attrs[:required]
       @value = attrs[:value]
       @options = []
+      @option_data = {}
     end
 
-    def add_option(id)
+    def add_option(id, data=nil)
       @options << id
+      @option_data[id] = data
     end
 
   end
diff --git a/lib/wizard/step_updater.rb b/lib/wizard/step_updater.rb
index aaf6208b4..543f55eff 100644
--- a/lib/wizard/step_updater.rb
+++ b/lib/wizard/step_updater.rb
@@ -23,6 +23,34 @@ class Wizard
       update_setting(:site_contact_username, fields, :site_contact_username)
     end
 
+    def update_colors(fields)
+      scheme_name = fields[:color_scheme]
+
+      theme = ColorScheme.themes.find {|s| s[:id] == scheme_name }
+
+      colors = []
+      theme[:colors].each do |name, hex|
+        colors << {name: name, hex: hex[1..-1] }
+      end
+
+      attrs = {
+        enabled: true,
+        name: I18n.t("wizard.step.colors.fields.color_scheme.options.#{scheme_name}"),
+        colors: colors
+      }
+
+      scheme = ColorScheme.where(via_wizard: true).first
+      if scheme.present?
+        attrs[:colors] = colors
+        revisor = ColorSchemeRevisor.new(scheme, attrs)
+        revisor.revise
+      else
+        attrs[:via_wizard] = true
+        scheme = ColorScheme.new(attrs)
+        scheme.save!
+      end
+    end
+
     def success?
       @errors.blank?
     end
diff --git a/public/images/wizard/discourse-small.png b/public/images/wizard/discourse-small.png
new file mode 100644
index 000000000..9fc9748d9
Binary files /dev/null and b/public/images/wizard/discourse-small.png differ
diff --git a/public/images/wizard/trout.png b/public/images/wizard/trout.png
new file mode 100644
index 000000000..5af72ee42
Binary files /dev/null and b/public/images/wizard/trout.png differ
diff --git a/spec/components/step_updater_spec.rb b/spec/components/step_updater_spec.rb
index df9826004..336c9fe33 100644
--- a/spec/components/step_updater_spec.rb
+++ b/spec/components/step_updater_spec.rb
@@ -21,7 +21,7 @@ describe Wizard::StepUpdater do
                      contact_url: 'http://example.com/custom-contact-url',
                      site_contact_username: user.username)
 
-      expect(updater.success?).to eq(true)
+      expect(updater).to be_success
       expect(SiteSetting.contact_email).to eq("eviltrout@example.com")
       expect(SiteSetting.contact_url).to eq("http://example.com/custom-contact-url")
       expect(SiteSetting.site_contact_username).to eq(user.username)
@@ -30,9 +30,39 @@ describe Wizard::StepUpdater do
     it "doesn't update when there are errors" do
       updater.update(contact_email: 'not-an-email',
                      site_contact_username: 'not-a-username')
-      expect(updater.success?).to eq(false)
+      expect(updater).to be_success
       expect(updater.errors).to be_present
     end
   end
 
+  context "colors step" do
+    let(:updater) { Wizard::StepUpdater.new(user, 'colors') }
+
+    context "with an existing color scheme" do
+      let!(:color_scheme) { Fabricate(:color_scheme, name: 'existing', via_wizard: true) }
+
+      it "updates the scheme" do
+        updater.update(color_scheme: 'dark')
+        expect(updater.success?).to eq(true)
+
+        color_scheme.reload
+        expect(color_scheme).to be_enabled
+
+      end
+    end
+
+    context "without an existing scheme" do
+
+      it "creates the scheme" do
+        updater.update(color_scheme: 'dark')
+        expect(updater.success?).to eq(true)
+
+        color_scheme = ColorScheme.where(via_wizard: true).first
+        expect(color_scheme).to be_present
+        expect(color_scheme).to be_enabled
+        expect(color_scheme.colors).to be_present
+      end
+    end
+  end
+
 end