Index: wp-includes/js/plupload/wp-plupload.dev.js
===================================================================
--- wp-includes/js/plupload/wp-plupload.dev.js	(revision 21007)
+++ wp-includes/js/plupload/wp-plupload.dev.js	(working copy)
@@ -4,6 +4,9 @@
 (function( exports, $ ) {
 	var Uploader;
 
+	if ( typeof _wpPluploadSettings === 'undefined' )
+		return;
+
 	/*
 	 * An object that helps create a WordPress uploader using plupload.
 	 *
@@ -27,8 +30,17 @@
 			},
 			key;
 
+		this.supports = {
+			upload: Uploader.browser.supported
+		};
+
+		this.supported = this.supports.upload;
+
+		if ( ! this.supported )
+			return;
+
 		// Use deep extend to ensure that multipart_params and other objects are cloned.
-		this.plupload = $.extend( true, { multipart_params: {} }, wpPluploadDefaults );
+		this.plupload = $.extend( true, { multipart_params: {} }, Uploader.defaults );
 		this.container = document.body; // Set default container.
 
 		// Extend the instance with options
@@ -68,10 +80,10 @@
 		this.param( this.params || {} );
 		delete this.params;
 
-		this.uploader.bind( 'Init', this.init );
-
 		this.uploader.init();
 
+		this.supports.dragdrop = this.uploader.features.dragdrop && ! Uploader.browser.mobile;
+
 		// Generate drag/drop helper classes.
 		(function( dropzone, supported ) {
 			var sensitivity = 50,
@@ -99,7 +111,7 @@
 				active = false;
 				dropzone.removeClass('drag-over');
 			});
-		}( this.dropzone, this.uploader.features.dragdrop ));
+		}( this.dropzone, this.supports.dragdrop ));
 
 		this.browser.on( 'mouseenter', this.refresh );
 
@@ -147,8 +159,13 @@
 			up.refresh();
 			up.start();
 		});
+
+		this.init();
 	};
 
+	// Adds the 'defaults' and 'browser' properties.
+	$.extend( Uploader, _wpPluploadSettings );
+
 	Uploader.uuid = 0;
 
 	Uploader.errorMap = {
@@ -200,4 +217,4 @@
 	});
 
 	exports.Uploader = Uploader;
-})( wp, jQuery );
\ No newline at end of file
+})( wp, jQuery );
Index: wp-includes/js/customize-loader.dev.js
===================================================================
--- wp-includes/js/customize-loader.dev.js	(revision 21007)
+++ wp-includes/js/customize-loader.dev.js	(working copy)
@@ -70,6 +70,10 @@
 			if ( this.active )
 				return;
 
+			// Load the full page on mobile devices.
+			if ( Loader.settings.browser.mobile )
+				return window.location = src;
+
 			this.active = true;
 			this.body.addClass('customize-loading');
 
Index: wp-includes/class-wp-customize-control.php
===================================================================
--- wp-includes/class-wp-customize-control.php	(revision 21007)
+++ wp-includes/class-wp-customize-control.php	(working copy)
@@ -331,7 +331,7 @@
 			$src = call_user_func( $this->get_url, $src );
 
 		?>
-		<label class="customize-image-picker">
+		<div class="customize-image-picker">
 			<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
 
 			<div class="customize-control-content">
@@ -366,7 +366,7 @@
 			<div class="actions">
 				<a href="#" class="remove"><?php _e( 'Remove Image' ); ?></a>
 			</div>
-		</label>
+		</div>
 		<?php
 	}
 
@@ -382,14 +382,20 @@
 	}
 
 	public function tab_upload_new() {
-		?>
-		<div class="upload-dropzone">
-			<?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
-		</div>
-		<div class="upload-fallback">
-			<span class="button-secondary"><?php _e('Select File'); ?></span>
-		</div>
-		<?php
+		if ( ! _device_can_upload() ) {
+			?>
+			<p><?php _e('The web browser on your device cannot be used to upload files. You may be able to use the <a href="http://wordpress.org/extend/mobile/">native app for your device</a> instead.'); ?></p>
+			<?php
+		} else {
+			?>
+			<div class="upload-dropzone">
+				<?php _e('Drop a file here or <a href="#" class="upload">select a file</a>.'); ?>
+			</div>
+			<div class="upload-fallback">
+				<span class="button-secondary"><?php _e('Select File'); ?></span>
+			</div>
+			<?php
+		}
 	}
 
 	public function tab_uploaded() {
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 21007)
+++ wp-includes/theme.php	(working copy)
@@ -1605,9 +1605,15 @@
 	$home_origin  = parse_url( home_url() );
 	$cross_domain = ( strtolower( $admin_origin[ 'host' ] ) != strtolower( $home_origin[ 'host' ] ) );
 
+	$browser = array(
+		'mobile' => wp_is_mobile(),
+		'ios'    => wp_is_mobile() && preg_match( '/iPad|iPod|iPhone/', $_SERVER['HTTP_USER_AGENT'] ),
+	);
+
 	$settings = array(
 		'url'           => esc_url( admin_url( 'customize.php' ) ),
 		'isCrossDomain' => $cross_domain,
+		'browser'       => $browser,
 	);
 
 	$script = 'var _wpCustomizeLoaderSettings = ' . json_encode( $settings ) . ';';
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 21007)
+++ wp-includes/media.php	(working copy)
@@ -1467,7 +1467,7 @@
 
 	$max_upload_size = wp_max_upload_size();
 
-	$settings = array(
+	$defaults = array(
 		'runtimes'            => 'html5,silverlight,flash,html4',
 		'file_data_name'      => 'async-upload', // key passed to $_FILE.
 		'multiple_queues'     => true,
@@ -1480,7 +1480,7 @@
 		'urlstream_upload'    => true,
 	);
 
-	$settings = apply_filters( 'plupload_default_settings', $settings );
+	$defaults = apply_filters( 'plupload_default_settings', $defaults );
 
 	$params = array(
 		'action' => 'upload-attachment',
@@ -1488,10 +1488,18 @@
 
 	$params = apply_filters( 'plupload_default_params', $params );
 	$params['_wpnonce'] = wp_create_nonce( 'media-form' );
-	$settings['multipart_params'] = $params;
+	$defaults['multipart_params'] = $params;
 
-	$script = 'var wpPluploadDefaults = ' . json_encode( $settings ) . ';';
+	$settings = array(
+		'defaults' => $defaults,
+		'browser'  => array(
+			'mobile'    => wp_is_mobile(),
+			'supported' => _device_can_upload(),
+		),
+	);
 
+	$script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';';
+
 	$data = $wp_scripts->get_data( 'wp-plupload', 'data' );
 	if ( $data )
 		$script = "$data\n$script";
Index: wp-admin/includes/class-wp-theme-install-list-table.php
===================================================================
--- wp-admin/includes/class-wp-theme-install-list-table.php	(revision 21007)
+++ wp-admin/includes/class-wp-theme-install-list-table.php	(working copy)
@@ -250,7 +250,7 @@
 	 */
 	function theme_installer() {
 		?>
-		<div id="theme-installer" class="wp-full-overlay">
+		<div id="theme-installer" class="wp-full-overlay expanded">
 			<div class="wp-full-overlay-sidebar">
 				<div class="wp-full-overlay-header">
 					<a href="#" class="close-full-overlay"><?php _e( '&larr; Close' ); ?></a>
Index: wp-admin/customize.php
===================================================================
--- wp-admin/customize.php	(revision 21007)
+++ wp-admin/customize.php	(working copy)
@@ -39,6 +39,19 @@
 wp_user_settings();
 _wp_admin_html_begin();
 
+$body_class = '';
+
+if ( wp_is_mobile() ) :
+	$body_class .= ' mobile';
+
+	?><meta name="viewport" id="viewport-meta" content="width=device-width, initial-scale=0.8, minimum-scale=0.5, maximum-scale=1.2"><?php
+endif;
+
+$is_ios = wp_is_mobile() && preg_match( '/iPad|iPod|iPhone/', $_SERVER['HTTP_USER_AGENT'] );
+
+if ( $is_ios )
+	$body_class .= ' ios';
+
 $admin_title = sprintf( __( '%1$s &#8212; WordPress' ), strip_tags( sprintf( __( 'Customize %s' ), $wp_customize->theme()->display('Name') ) ) );
 ?><title><?php echo $admin_title; ?></title><?php
 
@@ -46,7 +59,8 @@
 do_action( 'customize_controls_print_scripts' );
 ?>
 </head>
-<body class="wp-full-overlay">
+<body class="<?php echo esc_attr( $body_class ); ?>">
+<div class="wp-full-overlay expanded">
 	<form id="customize-controls" class="wrap wp-full-overlay-sidebar">
 		<?php wp_nonce_field( 'customize_controls' ); ?>
 		<div id="customize-header-actions" class="wp-full-overlay-header">
@@ -145,6 +159,10 @@
 			'isCrossDomain' => $cross_domain,
 			'fallback'      => $fallback_url,
 		),
+		'browser'  => array(
+			'mobile' => wp_is_mobile(),
+			'ios'    => $is_ios,
+		),
 		'settings' => array(),
 		'controls' => array(),
 	);
@@ -165,5 +183,6 @@
 	<script type="text/javascript">
 		var _wpCustomizeSettings = <?php echo json_encode( $settings ); ?>;
 	</script>
+</div>
 </body>
 </html>
Index: wp-admin/js/theme.dev.js
===================================================================
--- wp-admin/js/theme.dev.js	(revision 21007)
+++ wp-admin/js/theme.dev.js	(working copy)
@@ -41,7 +41,7 @@
 	});
 
 	preview.on( 'click', '.collapse-sidebar', function( event ) {
-		preview.toggleClass('collapsed');
+		preview.toggleClass( 'collapsed' ).toggleClass( 'expanded' );
 		event.preventDefault();
 	});
 
Index: wp-admin/js/customize-controls.dev.js
===================================================================
--- wp-admin/js/customize-controls.dev.js	(revision 21007)
+++ wp-admin/js/customize-controls.dev.js	(working copy)
@@ -148,6 +148,13 @@
 				success:   this.success
 			}, this.uploader || {} );
 
+			if ( this.uploader.supported ) {
+				if ( control.params.context )
+					control.uploader.param( 'post_data[context]', this.params.context );
+
+				control.uploader.param( 'post_data[theme]', api.settings.theme.stylesheet );
+			}
+
 			this.uploader = new wp.Uploader( this.uploader );
 
 			this.remover = this.container.find('.remove');
@@ -159,11 +166,6 @@
 			this.removerVisibility = $.proxy( this.removerVisibility, this );
 			this.setting.bind( this.removerVisibility );
 			this.removerVisibility( this.setting.get() );
-
-			if ( this.params.context )
-				control.uploader.param( 'post_data[context]', this.params.context );
-
-			control.uploader.param( 'post_data[theme]', api.settings.theme.stylesheet );
 		},
 		success: function( attachment ) {
 			this.setting.set( attachment.url );
@@ -182,7 +184,7 @@
 				init: function( up ) {
 					var fallback, button;
 
-					if ( up.features.dragdrop )
+					if ( this.supports.dragdrop )
 						return;
 
 					// Maintain references while wrapping the fallback button.
@@ -566,6 +568,7 @@
 			return window.location = api.settings.url.fallback;
 
 		var body = $( document.body ),
+			overlay = body.children('.wp-full-overlay'),
 			query, previewer, parent;
 
 		// Prevent the form from saving when enter is pressed.
@@ -702,7 +705,7 @@
 		});
 
 		$('.collapse-sidebar').click( function( event ) {
-			body.toggleClass( 'collapsed' );
+			overlay.toggleClass( 'collapsed' ).toggleClass( 'expanded' );
 			event.preventDefault();
 		});
 
Index: wp-admin/css/wp-admin.dev.css
===================================================================
--- wp-admin/css/wp-admin.dev.css	(revision 21007)
+++ wp-admin/css/wp-admin.dev.css	(working copy)
@@ -5255,27 +5255,23 @@
 	overflow: visible;
 	top: 0;
 	bottom: 0;
-	left: 300px;
+	left: 0;
 	right: 0;
 	height: 100%;
 	min-width: 0;
 }
 
-.wp-full-overlay.collapsed {
-	left: 0 !important;
-}
-
 .wp-full-overlay-sidebar {
 	-webkit-box-sizing: border-box;
 	-moz-box-sizing:    border-box;
 	box-sizing:         border-box;
 
-	position: absolute;
+	position: fixed;
 	width: 300px;
 	height: 100%;
 	top: 0;
 	bottom: 0;
-	right: 100%;
+	left: 0;
 	padding: 0;
 	margin: 0;
 	z-index: 10;
@@ -5288,6 +5284,19 @@
 	overflow: visible;
 }
 
+.wp-full-overlay.collapsed,
+.wp-full-overlay.expanded .wp-full-overlay-sidebar {
+	margin-left: 0 !important;
+}
+
+.wp-full-overlay.expanded {
+	margin-left: 300px;
+}
+
+.wp-full-overlay.collapsed .wp-full-overlay-sidebar {
+	margin-left: -300px;
+}
+
 .wp-full-overlay-sidebar:after {
 	content: '';
 	display: block;
@@ -5404,11 +5413,11 @@
 .wp-full-overlay-sidebar,
 .wp-full-overlay .collapse-sidebar,
 .wp-full-overlay-main {
-	-webkit-transition-property: left, right, top, bottom, width;
-	-moz-transition-property:    left, right, top, bottom, width;
-	-ms-transition-property:     left, right, top, bottom, width;
-	-o-transition-property:      left, right, top, bottom, width;
-	transition-property:         left, right, top, bottom, width;
+	-webkit-transition-property: left, right, top, bottom, width, margin;
+	-moz-transition-property:    left, right, top, bottom, width, margin;
+	-ms-transition-property:     left, right, top, bottom, width, margin;
+	-o-transition-property:      left, right, top, bottom, width, margin;
+	transition-property:         left, right, top, bottom, width, margin;
 
 	-webkit-transition-duration: 0.2s;
 	-moz-transition-duration:    0.2s;
Index: wp-admin/css/customize-controls.dev.css
===================================================================
--- wp-admin/css/customize-controls.dev.css	(revision 21007)
+++ wp-admin/css/customize-controls.dev.css	(working copy)
@@ -402,10 +402,6 @@
 	text-align: right;
 }
 
-.customize-section .customize-control-image .actions a {
-	display: block;
-}
-
 .customize-section .customize-control-image .library ul {
 	border-bottom: 1px solid #dfdfdf;
 	float: left;
@@ -456,7 +452,7 @@
 
 .customize-section .customize-control-image .library .thumbnail img {
 	display: block;
-	max-width: 220px;
+	max-width: 90%;
 	max-height: 80px;
 
 	margin: 5px auto;
@@ -479,6 +475,7 @@
 	text-align: center;
 	color: #777;
 	position: relative;
+	cursor: default;
 }
 
 .customize-section .customize-control-upload .upload-dropzone.supports-drag-drop,
@@ -491,7 +488,29 @@
 	transition:         border-color 0.1s;
 }
 
+.customize-section .customize-control-upload .library ul li,
+.customize-section .customize-control-image .library ul li {
+	cursor: pointer;
+}
+
 .customize-section .customize-control-upload .upload-dropzone.supports-drag-drop.drag-over,
 .customize-section .customize-control-image .upload-dropzone.supports-drag-drop.drag-over {
 	border-color: #83b4d8;
-}
\ No newline at end of file
+}
+
+/**
+ * iOS can't scroll iframes,
+ * instead it expands the iframe size to match the size of the content
+ */
+.ios .wp-full-overlay {
+	position: relative;
+}
+
+.ios #customize-preview {
+	position: relative;
+}
+
+.ios #customize-controls .wp-full-overlay-sidebar-content {
+	-webkit-overflow-scrolling: touch;
+}
+
