diff --git a/picture.admin.inc b/picture.admin.inc
index d9a1d74..5c8de54 100644
--- a/picture.admin.inc
+++ b/picture.admin.inc
@@ -216,3 +216,118 @@ function picture_admin_settings($form, &$form_state) {
 
   return system_settings_form($form);
 }
+
+/**
+ * Chooses which picture groups are available in the CKEditor image dialog.
+ */
+function picture_ckeditor_settings() {
+  $form = array();
+  $picture_groups = picture_get_mapping_options();
+  $ckeditor_groups = array();
+
+  // check if picture group mappings have been configured before proceeding.
+  if ($picture_groups) {
+    // create a settings form.
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('Choose which picture groups will be available in the CKEditor image dialog.'),
+      '#description' => 'See picture_wysiwyg.css for an example of how to style these images in your theme using the selectors suggested below.',
+    );
+
+    //retrieve pre-existing settings.
+    $ckeditor_groups = variable_get('picture_ckeditor_groups', array());
+
+    // loop through each picture group and place a checkbox and weight.
+    foreach ($picture_groups as $machine_name => $display_name) {
+      $form[$machine_name] = array(
+        '#type' => 'fieldset',
+        '#title' => t('@name picture group', array('@name' => $display_name)),
+      );
+      $form[$machine_name]['enabled'] = array(
+        '#type' => 'checkbox',
+        '#default_value' => isset($ckeditor_groups[$machine_name]) ? $ckeditor_groups[$machine_name]['enabled'] : 0,
+        '#title' => t('Include @name picture group in the CKEditor image dialog', array('@name' => $display_name)),
+      );
+      $form[$machine_name]['css'] = array(
+        '#type' => 'item',
+        '#markup' => 'Consider using the selector <code>span[data-picture-group="' . $machine_name . '"]</code> in your theme CSS.',
+      );
+      $form[$machine_name]['weight'] = array(
+        '#type' => 'select',
+        '#title' => t('Weight'),
+        '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)),
+        '#default_value' => isset($ckeditor_groups[$machine_name]) ? $ckeditor_groups[$machine_name]['weight'] : 1,
+        '#description' => t('Control the sort order of picture groups in the CKEditor "size" drop-down. Higher weights sink to the bottom of the list.'),
+      );
+      $form[$machine_name]['fallback'] = array(
+        '#type' => 'select',
+        '#title' => t('Fallback image style'),
+        '#options' => drupal_map_assoc(array_keys(image_styles())),
+        '#default_value' => isset($ckeditor_groups[$machine_name]) ? $ckeditor_groups[$machine_name]['fallback'] : NULL,
+      );
+    }
+    $form['#tree'] = TRUE;
+    $form['ckeditor_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label in the CKEditor image dialog'),
+      '#description' => t('This sets the label for the drop-down select box containing these picture groups in the CKEditor image dialog'),
+      '#default_value' => variable_get('picture_ckeditor_label', 'Image size (required)'),
+    );
+
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'Save',
+    );
+  }
+  return $form;
+}
+
+/**
+ * Validate handler for the picture_ckeditor_settings form.
+ * It checks that a fallback image style is selected for every
+ * picture group that has been enabled for the CKEditor image dialog.
+ */
+function picture_ckeditor_settings_validate($form, &$form_state) {
+  $picture_groups = picture_mapping_load();
+  $ckeditor_groups = array();
+  foreach ($picture_groups as $picture_group) {
+    $machine_name = $picture_group->machine_name;
+    if ($form_state['values'][$machine_name]['enabled'] == 1) {
+      if (empty($form_state['values'][$machine_name]['fallback'])) {
+        form_set_error($machine_name . '][fallback', t('Please choose a fallback image style for this picture group'));
+      }
+    }
+  }
+}
+
+/**
+ * Submit handler for the picture_ckeditor_settings form. Places chosen picture
+ * groups into the variables table.
+ */
+function picture_ckeditor_settings_submit($form, &$form_state) {
+  $picture_groups = picture_mapping_load();
+  $ckeditor_groups = array();
+
+  // Loop each picture group and record the settings.
+  foreach ($picture_groups as $picture_group) {
+    $machine_name = $picture_group->machine_name;
+    $ckeditor_groups[$machine_name]['enabled'] = $form_state['values'][$machine_name]['enabled'];
+    $ckeditor_groups[$machine_name]['weight'] = $form_state['values'][$machine_name]['weight'];
+    $ckeditor_groups[$machine_name]['fallback'] = $form_state['values'][$machine_name]['fallback'];
+  }
+
+  uasort($ckeditor_groups, 'picture_compare_weights');
+  variable_set('picture_ckeditor_groups', $ckeditor_groups);
+  variable_set('picture_ckeditor_label', $form_state['values']['ckeditor_label']);
+  drupal_set_message(t('Your settings have been saved'));
+}
+
+/**
+  * Helper function to sort picture groups for the CKEditor image dialog
+  */
+function picture_compare_weights($a, $b) {
+  if ($a['weight'] == $b['weight']) {
+    return 0;
+  }
+  return ($a['weight'] < $b['weight']) ? -1 : 1;
+}
diff --git a/picture.info b/picture.info
index 59cc9da..75d4bbe 100644
--- a/picture.info
+++ b/picture.info
@@ -4,3 +4,4 @@ core = 7.x
 dependencies[] = breakpoints
 configure = admin/config/media/picture
 package = Picture
+stylesheets[all][] = picture_wysiwyg.css
diff --git a/picture.module b/picture.module
index 523b24c..d8b9bfe 100644
--- a/picture.module
+++ b/picture.module
@@ -90,6 +90,17 @@ function picture_menu() {
     }
   }
 
+  $items['admin/config/media/picture/ckeditor'] = array(
+    'title' => 'CKEditor',
+    'type' => MENU_LOCAL_TASK,
+    'description' => 'Choose picture groups to present in the CKEditor image dialog',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('picture_ckeditor_settings'),
+    'access arguments' => array('administer pictures'),
+    'file' => 'picture.admin.inc',
+    'weight' => 0,
+  );
+
   return $items;
 }
 
@@ -687,6 +698,12 @@ function theme_picture($variables) {
         $attributes['data-' . $key] = $variables[$key];
       }
     }
+    // Add attributes that are already prefixed by 'data-'
+    foreach (array('data-picture-group', 'data-picture-align') as $key) {
+      if (isset($variables[$key])) {
+        $attributes[$key] = $variables[$key];
+      }
+    }
     $output[] = '<span data-picture=""' . drupal_attributes($attributes) . '>';
 
     // Add source tags to the output.
@@ -935,3 +952,282 @@ function picture_file_formatter_picture_settings($form, &$form_state, $settings)
 
   return $element;
 }
+
+/**
+ * Implements hook_filter_info().
+ */
+function picture_filter_info() {
+  $filters = array();
+  $filters['picture'] = array(
+    'title' => t('Make images responsive with the picture module'),
+    'description' => t('Replace img tags with markup that contains media width breakpoints. The appropriate image file size will be chosen.'),
+    'process callback' => '_picture_filter_process',
+    'tips callback' => '_picture_filter_tips',
+    //@TODO remove following cache line when development is finished.
+    'cache' => FALSE,
+    );
+
+  return $filters;
+}
+
+/**
+ * Process callback for inline image filter.
+ */
+function _picture_filter_process($text, $filter) {
+
+  // Find all img tags with a data-picture-group attribute.
+  preg_match_all('/<img.*?data-picture-group=".*?>/i', $text, $images);
+
+  if (!empty($images[0])) {
+    foreach ($images[0] as $image) {
+      // create the render array expected by theme_picture_formatter
+      $image_render_array = _picture_filter_prepare_image($image);
+      if (!$image_render_array) {
+        return $text;
+      }
+
+      // get the responsive markup for this image
+      $new_markup = theme('picture_formatter', $image_render_array);
+
+      //replace the original img tag with the responsive markup
+      $text = str_replace($image, $new_markup, $text);
+    }
+  }
+  return $text;
+}
+
+/**
+ * Prepares a Render Array for theme_picture_formatter().
+ * It is similar to picture_field_formatter_picture_view()
+ * with modifications for inline images.
+ *
+ * @param $image
+ *   An img tag
+ */
+function _picture_filter_prepare_image($image) {
+  // Parse the tag as xml.
+  $xml = simplexml_load_string('<image>' . html_entity_decode($image, ENT_QUOTES, "utf-8") . '</image>');
+  if (isset($xml->img[0]) && is_object($xml->img[0])) {
+    $attributes = array();
+    foreach ($xml->img[0]->attributes() as $a => $b) {
+      $attributes[$a] = (string) $b;
+    }
+  }
+
+  $image_render_array = array();
+  $breakpoint_styles = array();
+  $fallback_image_style = '';
+  $group_name = $attributes['data-picture-group'];
+  $mappings = picture_mapping_load($group_name);
+
+  if ($mappings) {
+    foreach ($mappings->mapping as $breakpoint_name => $multipliers) {
+      if (!empty($multipliers)) {
+        foreach ($multipliers as $multiplier => $image_style) {
+          if (!empty($image_style)) {
+            if (empty($fallback_image_style)) {
+              $fallback_image_style = $image_style;
+            }
+            if (!isset($breakpoint_styles[$breakpoint_name])) {
+              $breakpoint_styles[$breakpoint_name] = array();
+            }
+            $breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
+          }
+        }
+      }
+    }
+  }
+
+  $src = $attributes['src'];
+
+  $uri = picture_image_uri($src);
+  if (!$uri) {
+    return FALSE;
+  }
+
+  $image_info = image_get_info($uri);
+  if (!$image_info) {
+    // It's not an image
+    return FALSE;
+  }
+  $picture_groups = variable_get('picture_ckeditor_groups', array());
+  $image_render_array = array(
+    '#theme' => 'picture_formatter',
+    '#attached' => array('library' => array(
+      array('picture', 'matchmedia'),
+      array('picture', 'picturefill'),
+      array('picture', 'picture.ajax'),
+    )),
+    '#item' => array(
+      'style_name' => $picture_groups[$attributes['data-picture-group']]['fallback'],
+      'uri' => $uri,
+      'width' => $image_info['width'],
+      'height' => $image_info['height'],
+      'data-picture-group' => $attributes['data-picture-group'],
+      'data-picture-align' => isset($attributes['data-picture-align']) ? $attributes['data-picture-align'] : '',
+      'alt' => isset($attributes['alt']) ? $attributes['alt'] : '',
+      'title' => isset($attributes['title']) ? $attributes['title'] : '',
+      'filemime' => $image_info['mime_type'],
+    ),
+    '#image_style' => $picture_groups[$attributes['data-picture-group']]['fallback'],
+    '#breakpoints' => $breakpoint_styles,
+    '#path' => '',
+  );
+
+  return $image_render_array;
+
+}
+/**
+ * Implements picture filter tips callback.
+ */
+function _picture_filter_tips($filter, $format, $long = FALSE) {
+  $tips = 'Images with a data-picture-group attribute will be responsive, with a file size appropriate for the browser width.';
+
+  return $tips;
+}
+
+/**
+ * Implements hook_page_build().
+ *
+ * Add the image processing javascript to every page. This allows these scripts
+ * to get included in aggregation, which is probably good since there will be
+ * pictures needing this javascript on most pages. The library does not get
+ * added twice, even if it's attached to multiple fields that are also being
+ * displayed with responsive images. Maybe this should check that the
+ * page is not an admin theme page?
+ */
+function picture_page_build(&$page) {
+  drupal_add_library('picture', 'matchmedia', TRUE);
+  drupal_add_library('picture', 'picturefill', TRUE);
+  drupal_add_library('picture', 'picture.ajax', TRUE);
+}
+
+/**
+ * Helper function to figure out the uri of an image given the
+ * image src.
+ *
+ * @param
+ *   Image src starting with http://, https://, or root relative /.
+ *   It must point to a local file.
+ */
+function picture_image_uri($src) {
+  $uri = '';
+  // Prepare the src by removing http:// or https://
+  $src = preg_replace('/https?:\/\//', '', $src);
+  // Remove leading or trailing slashes
+  $src = trim($src, '/');
+
+  // List all visible stream wrappers. Make sure they're also local since the
+  // getDirectoryPath method exists only for classes that extend
+  // DrupalLocalStreamWrapper.
+  $local_visible_stream_wrappers = array_intersect_key(file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL), file_get_stream_wrappers(STREAM_WRAPPERS_VISIBLE));
+  $needles = array();
+  $matches = array();
+  foreach ($local_visible_stream_wrappers as $scheme => $data) {
+    $class = file_stream_wrapper_get_class($scheme);
+    $stream_wrapper = new $class();
+    // Trim leading or trailing slashes since the Directory could be root
+    // relative.
+    $needles[$scheme] = trim($stream_wrapper->getDirectoryPath(), '/');
+
+    // Check whether the file stream directory is at the beginning of
+    // the image src. Use === since strpos could return false.
+    if (strpos($src, $needles[$scheme]) === 0) {
+      $matches[$scheme] = $needles[$scheme];
+    }
+  }
+
+  // If one file scheme directory is a subdirectory of another file
+  // scheme directory, choose the longer one. This issue is possible with
+  // the following scenario:
+  // public file dir: /sites/default/files/
+  // private file dir: /sites/default/files/private/
+  // image src: /sites/default/files/private/the-image.jpg
+  // In this example, the intended scheme would be 'private'.
+
+  if (empty($matches)) {
+    // Can't figure out the Drupal uri.
+    return FALSE;
+  }
+  // Find the length of each matching directory path.
+  $lengths = array_map('strlen', $matches);
+
+  // Determine the key of the longest one.
+  $the_scheme = array_search(max($lengths), $lengths);
+
+  // Construct the Drupal uri.
+  $uri = $the_scheme . '://' . str_replace($matches[$the_scheme], '', $src);
+  $uri = file_stream_wrapper_uri_normalize($uri);
+
+  return $uri;
+}
+
+/**
+ * Implements hook_wysiwyg_plugin to modify the CKEditor image dialog for use
+ * with the picture module. The integration technique here is borrowed from
+ * imce_wysiwyg.
+ *
+ * Normally an array of plugin settings would be returned, but since it's
+ * problematic to have the WYSIWYG module load a plugin which doesn't have a
+ * button (an 'extension', in other words), this module takes care of
+ * loading the plugin itself. As a consequence, this plugin does not appear
+ * on the WYSIWYG button/plugin configuration page, and is always enabled
+ * for all WYSIWYG CKEditor profiles when picture groups have been enabled from
+ * /admin/config/media/picture/ckeditor
+ * @TODO: low priority - make a checkbox control loading of this extension. The
+ * imce_wysiwyg module does this by passing a CKEditor options array in the
+ * extension definition which is loaded only when the extension is enabled on
+ * the WYSIWYG config page.
+ *
+ * example code to get started with a checkbox would be:
+ *
+ * return array(
+ *   'picture_ckeditor' => array(
+ *       'extensions' => array('picture_ckeditor' => t('Responsive images
+ *       with the Picture module')),
+ *       'url' => 'http://drupal.org/projects/picture',
+ *       'load' => FALSE,
+ *     ),
+ * );
+ */
+function picture_wysiwyg_plugin($editor, $version) {
+
+  // Keep track of whether the JS has already been added since this hook is
+  // called multiple times on a page load.
+  static $picture_ckeditor_integrated = FALSE;
+
+  if ($editor == 'ckeditor' ) {
+    // Load our invocation scripts.
+    if (!$picture_ckeditor_integrated) {
+      // Create the Javascript array of picture group options
+      $picture_groups = picture_get_mapping_options();
+      $ckeditor_groups = variable_get('picture_ckeditor_groups', array());
+      $groups = array();
+      // CKEditor expects an array of options formatted as
+      // ['Display name', 'machine_name']
+      foreach ($picture_groups as $key => $value) {
+        if ($ckeditor_groups[$key]['enabled'] == 1) {
+          $groups[] = array($value, $key);
+        }
+      }
+      if (!empty($groups)) {
+        $groups[] = array('Not Set', 'not_set');
+        drupal_add_js(array(
+          'picture' => array(
+            'groups' => $groups,
+            'label' => variable_get('picture_ckeditor_label', 'Image size (required)'),
+            ),
+          ), 'setting');
+        drupal_add_js(drupal_get_path('module', 'picture') . '/picture_ckeditor.js');
+        $picture_ckeditor_integrated = TRUE;
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function picture_uninstall() {
+  variable_del('picture_ckeditor_groups');
+}
diff --git a/picture_ckeditor.js b/picture_ckeditor.js
new file mode 100644
index 0000000..c36c151
--- /dev/null
+++ b/picture_ckeditor.js
@@ -0,0 +1,182 @@
+/**
+ * @file picture_ckeditor.js
+ * Modify the CKEditor image dialog to insert responsive images.
+ *
+ * Supports inline responsive images with the Picture module.
+ * It also simplifies for the CKEditor image dialog.
+ */
+
+CKEDITOR.editorConfig = function( config )
+{
+  // this disables the browser resize handles since the width will now be set
+  // in the image dialog. This also prevents CKEditor from automatically adding
+  // pesky inline width and height styles, although these inline styles are
+  // still added when an image is dragged and dropped.
+  // Resize handles are also removed from tables as an unintended consequence.
+  config.disableObjectResizing = true;
+
+};
+
+// When opening a dialog, a 'definition' is created for it. For
+// each editor instance the 'dialogDefinition' event is then
+// fired. We can use this event to make customizations to the
+// definition of existing dialogs.
+CKEDITOR.on( 'dialogDefinition', function( event ) {
+  // Take the dialog name
+  var dialogName = event.data.name;
+  // The definition holds the structured data that is used to eventually
+  // build the dialog and we can use it to customize just about anything.
+  // In Drupal terms, it's sort of like CKEditor's version of a Forms API and
+  // what we're doing here is a bit like a hook_form_alter.
+  var dialogDefinition = event.data.definition;
+
+
+  // Resources for the following:
+  // Download: https://github.com/ckeditor/ckeditor-dev
+  // see /plugins/image/dialogs/image.js
+  // and refer to http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition
+  // visit: file:///[path_to_ckeditor-dev]/plugins/devtools/samples/devtools.html
+  // for an excellent way to find machine names for dialog elements
+  if (dialogName == 'image' ) {
+    dialogDefinition.removeContents( 'advanced' );
+    dialogDefinition.removeContents( 'Link' );
+    var infoTab = dialogDefinition.getContents( 'info' );
+    var altText = infoTab.get( 'txtAlt' );
+    var IMAGE = 1,
+        LINK = 2,
+        PREVIEW = 4,
+        CLEANUP = 8;
+    // updatePreview is copied from ckeditor image plugin
+    var updatePreview = function( dialog ) {
+      //Don't load before onShow.
+      if ( !dialog.originalElement || !dialog.preview )
+        return 1;
+
+      // Read attributes and update imagePreview;
+      dialog.commitContent( PREVIEW, dialog.preview );
+      return 0;
+    };
+    // add the select list for choosing the image width.
+    infoTab.add( {
+      type: 'select',
+      id: 'imageSize',
+      label: Drupal.settings.picture.label,
+      items: Drupal.settings.picture.groups,
+      'default': 'not_set',
+      onChange: function() {
+        // this = CKEDITOR.ui.dialog.select
+        var dialog = this.getDialog();
+        var element = dialog.originalElement;
+        element.setAttribute( 'data-picture-group', this.getValue() );
+        updatePreview( this.getDialog() );
+      },
+      setup: function( type, element ) {
+        if ( type == IMAGE ) {
+          var value = element.getAttribute( 'data-picture-group' );
+          this.setValue( value );
+        }
+      },
+      // create a custom data-picture-group attribute
+      commit: function( type, element ) {
+        if (type == IMAGE ) {
+          if ( this.getValue() || this.isChanged() ) {
+            element.setAttribute( 'data-picture-group', this.getValue() );
+          }
+        } else if ( type == PREVIEW ) {
+          element.setAttribute( 'data-picture-group', this.getValue() );
+        } else if ( type == CLEANUP ) {
+          element.setAttribute( 'data-picture-group', '' );
+        }
+      },
+      validate: function() {
+        if ( this.getValue() == 'not_set' ) {
+          alert('Please choose an image size');
+          return false;
+        } else {
+          return true;
+        }
+      }
+    },
+      //position before preview
+      'htmlPreview'
+    );
+
+    // Put a title attribute field on the main 'info' tab
+    infoTab.add( {
+      type: 'text',
+      id: 'txtTitle',
+      label: 'The title attribute is used as a tooltip when the mouse hovers over the image.',
+      onChange: function() {
+        updatePreview( this.getDialog() );
+      },
+      setup: function( type, element ) {
+        if ( type == IMAGE )
+          this.setValue( element.getAttribute( 'title' ) );
+      },
+      commit: function( type, element ) {
+        if ( type == IMAGE ) {
+          if ( this.getValue() || this.isChanged() )
+            element.setAttribute( 'title', this.getValue() );
+        } else if ( type == PREVIEW ) {
+          element.setAttribute( 'title', this.getValue() );
+        } else if ( type == CLEANUP ) {
+          element.removeAttribute( 'title' );
+        }
+      }
+    },
+      // position before the imageSize select box
+      //'imageSize'
+      'htmlPreview'
+    );
+
+    // add a select widget to choose image alignment
+    infoTab.add( {
+      type: 'select',
+      id: 'imageAlign',
+      label: 'Image Alignment',
+      items: [ [ 'Not Set', '' ], [ 'Left', 'left'],
+               [ 'Right', 'right' ], [ 'Center', 'center'] ],
+      'default': '',
+      onChange: function() {
+        // this = CKEDITOR.ui.dialog.select
+        updatePreview( this.getDialog() );
+      },
+      setup: function( type, element ) {
+        if ( type == IMAGE ) {
+          var value = element.getAttribute( 'data-picture-align' );
+          this.setValue( value );
+        }
+      },
+      // created a custom data-picture-align attribute since working with classes
+      // is more difficult. If we used classes, then we'd have to search for
+      // exisiting alignment classes and remove them before adding a new one.
+      // With the custom attribute we can always just overwrite it's value.
+      commit: function( type, element ) {
+        if (type == IMAGE ) {
+          if ( this.getValue() || this.isChanged() ) {
+            element.setAttribute( 'data-picture-align', this.getValue() );
+          }
+        } else if ( type == PREVIEW ) {
+          element.setAttribute( 'data-picture-align', this.getValue() );
+        } else if ( type == CLEANUP ) {
+          element.setAttribute( 'data-picture-align', '' );
+        }
+      }
+
+    },
+      //position before imageSize
+      'imageSize'
+    );
+
+    // Improve the alt field label. Copied from Drupal's image field.
+    altText.label = 'The alt attribute may be used by search engines, and screen readers.';
+
+    // Remove a bunch of extraneous fields. These properties will be set in
+    // the theme or module CSS.
+    infoFieldsRemove = [ 'cmbAlign', 'txtWidth', 'txtHeight', 'ratioLock', 'txtBorder',
+                     'txtHSpace', 'txtVSpace' ];
+    for( i = 0; i < infoFieldsRemove.length; i++ ) {
+      infoTab.remove( infoFieldsRemove[i] );
+    }
+  }
+});
diff --git a/picture_wysiwyg.css b/picture_wysiwyg.css
new file mode 100644
index 0000000..5b2086b
--- /dev/null
+++ b/picture_wysiwyg.css
@@ -0,0 +1,36 @@
+/* This CSS file needs to be included either in the theme used for
+* editing content in order to be included in the WYSIWYG edit iframe,
+* or specifically included in the WYSIWYG config page's
+* "Define CSS" textfield.
+*/
+span[data-picture-align="left"], img[data-picture-align="left"]  {
+  float: left;
+}
+span[data-picture-align="right"], img[data-picture-align="right"]  {
+  float: right;
+}
+span[data-picture-align="center"], img[data-picture-align="center"]  {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+/* Remove ugly boarders that bunch up in the image dialog table. */
+.cke_dialog_body tr td:last-child {
+  border-right: 0px;
+}
+/* The following is an example of what you could put in your theme
+ * to control the size of images. It is formatted as
+ * span[data-picture-group="[The machine name of your picture group]"
+span[data-picture-group="wide"] {
+  width: 100%;
+}
+span[data-picture-group="normal"] {
+  width: 50%;
+}
+span[data-picture-group="narrow"] {
+  width: 33%;
+}
+span[data-picture-group] img {
+  width: 100%;
+  height: auto;
+}*/
