Index: wp-content/themes/twentyfourteen/inc/customizer.php
===================================================================
--- wp-content/themes/twentyfourteen/inc/customizer.php	(revision 25998)
+++ wp-content/themes/twentyfourteen/inc/customizer.php	(working copy)
@@ -15,6 +15,21 @@
  * @param WP_Customize_Manager $wp_customize Theme Customizer object.
  */
 function twentyfourteen_customize_register( $wp_customize ) {
+	// Define custom customizer control for the number input type.
+	class Customize_Number_Control extends WP_Customize_Control {
+		public $type = 'number';
+		public $min  = 1;
+		public $max  = 15;
+		
+		public function render_content() {
+			?>
+			<label>
+			<span class="customize-control-title"><?php echo $this->label; ?></span>
+			<input type="number" value="<php echo esc_attr( $this->value() ); ?>" min="<?php echo $this->min; ?>" max="<?php echo $this->max; ?>" <?php $this->link(); ?> style="width: 50px;" />
+			<?php
+		}
+	}
+
 	// Add postMessage support for site title and description.
 	$wp_customize->get_setting( 'blogname' )->transport        = 'postMessage';
 	$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
@@ -40,8 +55,6 @@
 	// Add the featured content layout setting and control.
 	$wp_customize->add_setting( 'featured_content_layout', array(
 		'default'    => 'grid',
-		'type'       => 'theme_mod',
-		'capability' => 'edit_theme_options',
 	) );
 
 	$wp_customize->add_control( 'featured_content_layout', array(
@@ -53,10 +66,61 @@
 			'slider' => __( 'Slider', 'twentyfourteen' ),
 		),
 	) );
+
+	// Add Featured Content settings.
+	$wp_customize->add_setting( 'featured_content_tag_name', array(
+		'default'           => 'featured',
+		'sanitize_callback' => 'twentyfourteen_sanitize_fc_tag',
+	) );
+	$wp_customize->add_setting( 'featured_content_quantity', array(
+		'default'           => 6,
+		'sanitize_callback' => 'twentyfourteen_sanitize_fc_quantity',
+	) );
+	$wp_customize->add_setting( 'featured_content_hide_tag', array(
+		'default'           => true,
+	) );
+	
+	// Add Featured Content controls.
+	$wp_customize->add_control( 'featured_content_tag_name', array( 
+		'label'    => __( 'Tag name' ),
+		'section'  => 'featured_content',
+	) );
+	$wp_customize->add_control( new Customize_Number_Control( $wp_customize, 'featured_content_quantity', array(
+		'label'    => __( 'Number of posts' ),
+		'section'  => 'featured_content',
+		'min'      => 1,		
+		'max'      => 6,		
+	) ) );
+	$wp_customize->add_control( 'featured_content_hide_tag', array(
+		'label'    => __( 'Hide tag from displaying in post meta and tag clouds.' ),
+		'section'  => 'featured_content',
+		'type'     => 'checkbox',
+	) );
+
 }
 add_action( 'customize_register', 'twentyfourteen_customize_register' );
 
 /**
+ * Enqueue the tag suggestion script.
+ *
+ * @since Twenty Fourteen 1.0
+ */
+function twentyfourteen_customize_controls_js() {
+	wp_enqueue_script( 'twentyfourteen-featured-content-admin', get_template_directory_uri() . '/js/featured-content-admin.js', array( 'jquery', 'suggest' ), '20131022', true );
+}
+add_action( 'customize_controls_enqueue_scripts', 'twentyfourteen_customize_controls_js' );
+
+/**
+ * ajaxurl is not defined in the customizer, and we need it for the featued content suggest script.
+ *
+ * @todo This should probably be in core.
+ */
+function twentyfourteen_customize_controls_print_scripts() {
+	echo '<script type="text/javascript">ajaxurl = "' . admin_url('admin-ajax.php') . '"; </script>';
+}
+add_action( 'customize_controls_print_scripts', 'twentyfourteen_customize_controls_print_scripts' );
+
+/**
  * Bind JS handlers to make Theme Customizer preview reload changes asynchronously.
  *
  * @since Twenty Fourteen 1.0
@@ -67,6 +131,55 @@
 add_action( 'customize_preview_init', 'twentyfourteen_customize_preview_js' );
 
 /**
+ * Sanitize featured content quantity
+ *
+ * @param int $input The value to sanitize.
+ * @return int $quantity A number between 1 and 6.
+ *
+ * @since Twenty Fourteen 1.0
+ */
+function twentyfourteen_sanitize_fc_quantity( $input ) {
+	$quantity = absint( $input );
+
+	if ( $quantity > 6 )
+		$quantity = 6;
+	else if ( 1 > $quantity )
+		$quantity = 1;
+
+	return $quantity;
+}
+
+/**
+ * Validate the featured content tag and define the corresponding id.
+ *
+ * Make sure that the user-specified tag exists,
+ * and save its id if it does. This function 
+ * will also delete the transient set in
+ * Featured_Content::get_featured_content().
+ *
+ * @param string $input User-specified tag name.
+ * @return string $output The tag name if it exists, or an empty string.
+ */
+function twentyfourteen_sanitize_fc_tag( $input ) {
+	$output = '';
+	if ( $input ) {
+		$new_tag = wp_create_tag( $input );
+		if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) )
+			$tag = get_term( $new_tag['term_id'], 'post_tag' );
+		if ( isset( $tag->term_id ) ) {
+			set_theme_mod( 'featured_content_tag_id', $tag->term_id );
+			$output = $tag->name;
+		}
+	} else {
+		delete_theme_mod( 'featured_content_tag_id' );
+	}
+	
+	delete_transient( 'featured_content_ids' );
+
+	return $output;
+}
+
+/**
  * Generate two variants of the accent color, return the original, and
  * save the others as theme mods.
  *
Index: wp-content/themes/twentyfourteen/inc/featured-content.php
===================================================================
--- wp-content/themes/twentyfourteen/inc/featured-content.php	(revision 25998)
+++ wp-content/themes/twentyfourteen/inc/featured-content.php	(working copy)
@@ -69,7 +69,6 @@
 			self::$max_posts = absint( $theme_support[0]['max_posts'] );
 
 		add_filter( $filter,                 array( __CLASS__, 'get_featured_posts' ) );
-		add_action( 'admin_init',            array( __CLASS__, 'register_setting' ) );
 		add_action( 'save_post',             array( __CLASS__, 'delete_transient' ) );
 		add_action( 'delete_post_tag',       array( __CLASS__, 'delete_post_tag' ) );
 		add_action( 'pre_get_posts',         array( __CLASS__, 'pre_get_posts' ) );
@@ -95,7 +94,7 @@
 		if ( false === $post_ids )
 			return false;
 
-		// No need to query if there is are no featured posts.
+		// No need to query if there are no featured posts.
 		if ( empty( $post_ids ) )
 			return array();
 
@@ -300,54 +299,6 @@
 	}
 
 	/**
-	 * Register custom setting on the Settings -> Reading screen
-	 *
-	 * @uses Featured_Content::render_form()
-	 * @uses Featured_Content::validate_settings()
-	 *
-	 * @return void
-	 */
-	public static function register_setting() {
-		add_settings_field( 'featured-content', __( 'Featured content', 'twentyfourteen' ), array( __CLASS__, 'render_form' ), 'reading' );
-		register_setting( 'reading', 'featured-content', array( __CLASS__, 'validate_settings' ) );
-	}
-
-	/**
-	 * Render the form fields for Settings -> Reading screen
-	 *
-	 * @return void
-	 */
-	public static function render_form() {
-		$settings = self::get_setting();
-
-		$tag_name = '';
-		if ( ! empty( $settings['tag-id'] ) ) {
-			$tag = get_term( $settings['tag-id'], 'post_tag' );
-			if ( ! is_wp_error( $tag ) && isset( $tag->name ) )
-				$tag_name = $tag->name;
-		}
-
-		wp_enqueue_script( 'twentyfourteen-admin', get_template_directory_uri() . '/js/featured-content-admin.js', array( 'jquery', 'suggest' ), '20131016', true );
-		?>
-		<div id="featured-content-ui">
-			<p>
-				<label for="featured-content-tag-name"><?php echo _e( 'Tag name:', 'twentyfourteen' ); ?></label>
-				<input type="text" id="featured-content-tag-name" name="featured-content[tag-name]" value="<?php echo esc_attr( $tag_name ); ?>">
-				<input type="hidden" id="featured-content-tag-id" name="featured-content[tag-id]" value="<?php echo esc_attr( $settings['tag-id'] ); ?>">
-			</p>
-			<p>
-				<label for="featured-content-quantity"><?php _e( 'Number of posts:', 'twentyfourteen' ); ?></label>
-				<input class="small-text" type="number" step="1" min="1" max="<?php echo esc_attr( self::$max_posts ); ?>" id="featured-content-quantity" name="featured-content[quantity]" value="<?php echo esc_attr( $settings['quantity'] ); ?>">
-			</p>
-			<p>
-				<input type="checkbox" id="featured-content-hide-tag" name="featured-content[hide-tag]" <?php checked( $settings['hide-tag'], 1 ); ?>>
-				<label for="featured-content-hide-tag"><?php _e( 'Hide tag from displaying in post meta and tag clouds.', 'twentyfourteen' ); ?></label>
-			</p>
-		</div>
-		<?php
-	}
-
-	/**
 	 * Get settings
 	 *
 	 * Get all settings recognized by this module. This function will return
@@ -357,13 +308,15 @@
 	 * In the event that you only require one setting, you may pass its name
 	 * as the first parameter to the function and only that value will be returned.
 	 *
-	 * @uses Featured_Content::self::sanitize_quantity()
-	 *
 	 * @param string $key The key of a recognized setting.
 	 * @return mixed Array of all settings by default. A single value if passed as first parameter.
 	 */
 	public static function get_setting( $key = 'all' ) {
-		$saved = (array) get_option( 'featured-content' );
+		$saved = array( 
+			'hide-tag' => get_theme_mod( 'featured_content_hide_tag' ),
+			'quantity' => get_theme_mod( 'featured_content_quantity' ),
+			'tag-id'   => get_theme_mod( 'featured_content_tag_id' ),
+		);
 
 		$defaults = array(
 			'hide-tag' => 1,
@@ -373,7 +326,6 @@
 
 		$options = wp_parse_args( $saved, $defaults );
 		$options = array_intersect_key( $options, $defaults );
-		$options['quantity'] = self::sanitize_quantity( $options['quantity'] );
 
 		if ( 'all' != $key ) {
 			if ( isset( $options[$key] ) )
@@ -384,65 +336,6 @@
 
 		return $options;
 	}
-
-	/**
-	 * Validate settings
-	 *
-	 * Make sure that all user supplied content is in an
-	 * expected format before saving to the database. This
-	 * function will also delete the transient set in
-	 * Featured_Content::get_featured_content().
-	 *
-	 * @uses Featured_Content::self::sanitize_quantity()
-	 * @uses Featured_Content::self::delete_transient()
-	 *
-	 * @param array $input
-	 * @return array $output
-	 */
-	public static function validate_settings( $input ) {
-		$output = array();
-
-		if ( isset( $input['tag-id'] ) )
-			$output['tag-id'] = absint( $input['tag-id'] );
-
-		if ( isset( $input['tag-name'] ) && ! empty( $input['tag-name'] ) ) {
-			$new_tag = wp_create_tag( $input['tag-name'] );
-			if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) )
-				$tag = get_term( $new_tag['term_id'], 'post_tag' );
-			if ( isset( $tag->term_id ) )
-				$output['tag-id'] = $tag->term_id;
-		} else {
-			unset( $output['tag-id'] );
-		}
-
-		if ( isset( $input['quantity'] ) )
-			$output['quantity'] = self::sanitize_quantity( $input['quantity'] );
-
-		$output['hide-tag'] = ( isset( $input['hide-tag'] ) ) ? 1 : 0;
-
-		self::delete_transient();
-
-		return $output;
-	}
-
-	/**
-	 * Sanitize quantity
-	 *
-	 * @param int $input The value to sanitize.
-	 * @return int A number between 1 and FeaturedContent::$max_posts.
-	 *
-	 * @uses Featured_Content::$max_posts
-	 */
-	public static function sanitize_quantity( $input ) {
-		$quantity = absint( $input );
-
-		if ( $quantity > self::$max_posts )
-			$quantity = self::$max_posts;
-		else if ( 1 > $quantity )
-			$quantity = 1;
-
-		return $quantity;
-	}
 }
 
 Featured_Content::setup();
\ No newline at end of file
Index: wp-content/themes/twentyfourteen/js/featured-content-admin.js
===================================================================
--- wp-content/themes/twentyfourteen/js/featured-content-admin.js	(revision 25998)
+++ wp-content/themes/twentyfourteen/js/featured-content-admin.js	(working copy)
@@ -1,3 +1,3 @@
 jQuery( document ).ready( function( $ ) {
-	$( '#featured-content-tag-name' ).suggest( ajaxurl + '?action=ajax-tag-search&tax=post_tag', { delay: 500, minchars: 2 } );
+	$( '#customize-control-featured_content_tag_name input' ).suggest( ajaxurl + '?action=ajax-tag-search&tax=post_tag', { delay: 500, minchars: 2 } );
 } );
\ No newline at end of file
