MDL-66883 theme_boost: use bootstrap native switches
authorBas Brands <bas@moodle.com>
Wed, 9 Oct 2019 13:44:42 +0000 (15:44 +0200)
committerBas Brands <bas@moodle.com>
Thu, 19 Dec 2019 12:03:24 +0000 (13:03 +0100)
14 files changed:
message/templates/message_drawer_view_settings_body_content.mustache
message/templates/message_drawer_view_settings_body_content_notification_preferences.mustache
mod/forum/amd/build/discussion_list.min.js
mod/forum/amd/build/discussion_list.min.js.map
mod/forum/amd/src/discussion_list.js
mod/forum/templates/discussion_list.mustache
mod/forum/templates/inpage_reply_v2.mustache
mod/forum/templates/setting_switch.mustache
mod/forum/tests/behat/discussion_subscriptions.feature
mod/forum/tests/behat/forum_subscriptions_default.feature
theme/boost/scss/moodle/core.scss
theme/boost/scss/preset/default.scss
theme/boost/style/moodle.css
theme/classic/style/moodle.css

index 9865378..f359f34 100644 (file)
 
     <h3 class="mb-2 mt-4 h6 font-weight-bold">{{#str}} general, core {{/str}}</h3>
     <div data-preference="entertosend">
-        <span class="switch">
-            <input type="checkbox"
-                id="enter-to-send-{{uniqid}}"
-                {{#entertosend}}checked{{/entertosend}}
-            >
-            <label for="enter-to-send-{{uniqid}}">
+        <div class="custom-control custom-switch">
+            <input type="checkbox" class="custom-control-input" id="enter-to-send-{{uniqid}}" {{#entertosend}}checked{{/entertosend}}>
+            <label class="custom-control-label" for="enter-to-send-{{uniqid}}">
                 {{#str}} useentertosend, core_message {{/str}}
             </label>
-        </span>
+        </div>
     </div>
 </div>
 {{/settings}}
\ No newline at end of file
index 19a866b..8d84c8c 100644 (file)
 
 <div data-preference="notifications" class="d-flex flex-column">
     {{#processors}}
-        <span class="switch">
-            <input type="checkbox"
-                id="{{name}}-{{uniqid}}"
+
+        <div class="custom-control custom-switch">
+            <input type="checkbox" class="custom-control-input" id="{{name}}-{{uniqid}}"
                 data-name="{{name}}"
                 {{#checked}}checked{{/checked}}
                 {{#locked}}disabled{{/locked}}
             >
-            <label for="{{name}}-{{uniqid}}">{{displayname}}{{#locked}} ({{lockedmessage}}){{/locked}}</label>
-        </span>
+            <label class="custom-control-label" for="{{name}}-{{uniqid}}">
+                {{displayname}}{{#locked}} ({{lockedmessage}}){{/locked}}
+            </label>
+        </div>
     {{/processors}}
 </div>
index 730af05..6b58d4d 100644 (file)
Binary files a/mod/forum/amd/build/discussion_list.min.js and b/mod/forum/amd/build/discussion_list.min.js differ
index 8da1ac0..c53d199 100644 (file)
Binary files a/mod/forum/amd/build/discussion_list.min.js.map and b/mod/forum/amd/build/discussion_list.min.js.map differ
index 1fb1bcd..1f9477d 100644 (file)
@@ -133,7 +133,7 @@ define([
                 var stringKey = context.userstate.subscribed ? 'unsubscribediscussion' : 'subscribediscussion';
                 return Str.get_string(stringKey, 'mod_forum')
                     .then(function(string) {
-                        toggleElement.closest('td').find('label[for="' + toggleId + '"]').text(string);
+                        toggleElement.closest('td').find('label[for="' + toggleId + '"]').find('span').text(string);
                         return string;
                     });
             });
index 74dc110..226394c 100644 (file)
                             {{#forum.capabilities.subscribe}}
                                 <td class="text-center align-middle fit-content px-2">
                                     {{#discussion}}
-                                        <span class="switch sr-only-label">
+                                        <div class="d-inline custom-control custom-switch mb-1">
                                             <input
                                                 type="checkbox"
+                                                class="custom-control-input"
                                                 id="subscription-toggle-{{id}}"
                                                 data-type="subscription-toggle"
                                                 data-action="toggle"
                                                 data-discussionid="{{id}}"
                                                 data-forumid="{{forumid}}"
                                                 {{#userstate.subscribed}}data-targetstate="0" checked{{/userstate.subscribed}}
-                                                {{^userstate.subscribed}}data-targetstate="1"{{/userstate.subscribed}}
-                                            >
-                                            <label for="subscription-toggle-{{id}}">
-                                                {{#userstate.subscribed}}
-                                                    {{#str}}unsubscribediscussion, forum{{/str}}
-                                                {{/userstate.subscribed}}
-                                                {{^userstate.subscribed}}
-                                                    {{#str}}subscribediscussion, forum{{/str}}
-                                                {{/userstate.subscribed}}
+                                                {{^userstate.subscribed}}data-targetstate="1"{{/userstate.subscribed}}>
+                                            <label class="custom-control-label" for="subscription-toggle-{{id}}">
+                                                <span class="sr-only">
+                                                    {{#userstate.subscribed}}
+                                                        {{#str}}unsubscribediscussion, forum{{/str}}
+                                                    {{/userstate.subscribed}}
+                                                    {{^userstate.subscribed}}
+                                                        {{#str}}subscribediscussion, forum{{/str}}
+                                                    {{/userstate.subscribed}}
+                                                </span>
                                             </label>
-                                        </span>
+                                        </div>
                                     {{/discussion}}
                                 </td>
                             {{/forum.capabilities.subscribe}}
index 336a3be..8513c14 100644 (file)
                     </button>
                     {{#canreplyprivately}}
                     <div class="form-check form-check-inline">
-                        <span class="switch">
-                            <input name="privatereply" type="checkbox" id="private-reply-checkbox-{{uniqid}}">
-                            <label class="mb-0" for="private-reply-checkbox-{{uniqid}}">
+                        <div class="custom-control custom-switch">
+                            <input name="privatereply" type="checkbox" class="custom-control-input" id="private-reply-checkbox-{{uniqid}}">
+                            <label class="custom-control-label" for="private-reply-checkbox-{{uniqid}}">
                                 {{#str}} privatereply, forum {{/str}}
                             </label>
-                        </span>
+                        </div>
                     </div>
                     {{/canreplyprivately}}
                     <button
index 35d283b..20f50ab 100644 (file)
 
 }}
 <div>
-    <span class="switch">
-        <input type="checkbox" id="{{$switchid}}{{uniqid}}{{/switchid}}"
-               data-type="{{$type}}toggle-switch{{/type}}"
-               data-action="toggle" class="hidden"
-            {{$otherattributes}}{{/otherattributes}}/>
-        <label for="{{$switchid}}{{uniqid}}{{/switchid}}" class="line-height-4">
+    <div class="custom-control custom-switch mb-1">
+        <input type="checkbox" class="custom-control-input" id="{{$switchid}}{{uniqid}}{{/switchid}}"
+            data-type="{{$type}}toggle-switch{{/type}}" data-action="toggle"
+            {{$otherattributes}}{{/otherattributes}}>
+        <label class="custom-control-label" for="{{$switchid}}{{uniqid}}{{/switchid}}">
             {{$labeltext}}{{/labeltext}}
         </label>
-    </span>
+    </div>
 </div>
index e193928..212b724 100644 (file)
@@ -37,15 +37,15 @@ Feature: A user can control their own subscription preferences for a discussion
     Then I can subscribe to this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can subscribe to this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can subscribe to this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can subscribe to this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
@@ -80,15 +80,15 @@ Feature: A user can control their own subscription preferences for a discussion
     Then I can unsubscribe from this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can unsubscribe from this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can unsubscribe from this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can unsubscribe from this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
@@ -123,7 +123,7 @@ Feature: A user can control their own subscription preferences for a discussion
     And I can subscribe to this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can subscribe to this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
@@ -168,7 +168,7 @@ Feature: A user can control their own subscription preferences for a discussion
     And I can subscribe to this forum
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject one" "table_row"
     And I can subscribe to this forum
     And "Unsubscribe from this discussion" "checkbox" should exist in the "Test post subject one" "table_row"
     And "Subscribe to this discussion" "checkbox" should exist in the "Test post subject two" "table_row"
index af266b3..637e8b3 100644 (file)
@@ -123,7 +123,7 @@ Feature: A user can control their default discussion subscription settings
     And I log in as "student1"
     And I am on "Course 1" course homepage
     And I follow "Test forum name"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject" "table_row"
     And I follow "Test post subject"
     When I follow "Reply"
     And I click on "Advanced" "button"
@@ -132,7 +132,7 @@ Feature: A user can control their default discussion subscription settings
     And I log in as "student2"
     And I am on "Course 1" course homepage
     And I follow "Test forum name"
-    And I click on "label[for^=subscription-toggle]" "css_element" in the "Test post subject" "table_row"
+    And I click on "input[id^=subscription-toggle]" "css_element" in the "Test post subject" "table_row"
     And I follow "Test post subject"
     And I follow "Reply"
     And I click on "Advanced" "button"
index a7fa7e0..d8adf79 100644 (file)
@@ -2158,125 +2158,6 @@ div.editor_atto_toolbar button .icon {
     }
 }
 
-$switch-height: 1.25rem !default;
-$switch-height-half: ($switch-height / 2) !default;
-$switch-width: ($switch-height * 2) !default;
-$switch-border-radius: $switch-height !default;
-$switch-bg: $gray-300 !default;
-$switch-bg-height: 1rem !default;
-$switch-bg-height-half: ($switch-bg-height / 2) !default;
-$switch-checked-bg: rgba(map-get($theme-colors, 'primary'), .4) !default;
-$switch-checked-thumb-bg: map-get($theme-colors, 'primary') !default;
-$switch-disabled-bg: $gray-200 !default;
-$switch-disabled-color: $gray-600 !default;
-$switch-disabled-thumb-bg: $gray-600 !default;
-$switch-thumb-bg: $white !default;
-$switch-thumb-border-radius: 50% !default;
-$switch-thumb-size: $switch-height !default;
-$switch-thumb-size-half: $switch-height-half !default;
-$switch-focus-box-shadow: 0 0 0 ($input-btn-focus-width * 2) rgba(map-get($theme-colors, 'primary'), .25);
-$switch-transition: .2s all !default;
-
-.switch {
-    position: relative;
-    display: inline-block;
-
-    input {
-        float: left;
-        width: 1px;
-        transform: translateX(1px);
-        padding: 0;
-        margin: 0;
-        opacity: 0;
-        line-height: $switch-height;
-
-        + label {
-            position: relative;
-            min-height: $switch-height;
-            min-width: $switch-width;
-            line-height: $switch-height;
-            border-radius: $switch-border-radius;
-            display: inline-block;
-            cursor: pointer;
-            outline: none;
-            user-select: none;
-            padding-left: ($switch-width + .5rem);
-        }
-
-        + label::before,
-        + label::after {
-            content: '';
-            position: absolute;
-            left: 0;
-            bottom: 0;
-            display: block;
-        }
-
-        + label::before {
-            right: 0;
-            height: $switch-bg-height;
-            width: $switch-width;
-            top: calc(50% - #{$switch-bg-height-half});
-            background-color: $switch-bg;
-            border-radius: $switch-border-radius;
-            transition: $switch-transition;
-        }
-
-        + label::after {
-            left: 0;
-            width: $switch-thumb-size;
-            height: $switch-thumb-size;
-            top: calc(50% - #{$switch-thumb-size-half});
-            border-radius: $switch-thumb-border-radius;
-            background-color: $switch-thumb-bg;
-            transition: $switch-transition;
-            box-shadow:
-                0 1px 3px 0 rgba(0, 0, 0, 0.2),
-                0 1px 1px 0 rgba(0, 0, 0, 0.14),
-                0 2px 1px -1px rgba(0, 0, 0, 0.12);
-        }
-
-        &:checked + label::before {
-            background-color: $switch-checked-bg;
-        }
-
-        &:checked + label::after {
-            margin-left: $switch-height;
-            background-color: $switch-checked-thumb-bg;
-        }
-
-        &:focus + label::before {
-            outline: none;
-        }
-
-        &:focus + label::after {
-            outline: none;
-            box-shadow: $switch-focus-box-shadow;
-        }
-
-        &:disabled + label {
-            color: $switch-disabled-color;
-            cursor: not-allowed;
-        }
-
-        &:disabled + label::before {
-            background-color: $switch-disabled-bg;
-        }
-
-        &:disabled + label::after {
-            background-color: $switch-disabled-thumb-bg;
-        }
-    }
-
-    &.sr-only-label {
-        input + label {
-            text-indent: -9999px;
-            margin-bottom: 0;
-            padding-left: 0;
-        }
-    }
-}
-
 .paged-content-page-container {
     min-height: 3.125rem;
 }
index 39d8daf..c44d3ac 100644 (file)
@@ -60,6 +60,9 @@ $alert-border-width:                0 !default;
 
 $card-group-margin: .25rem;
 
+// Custom control size
+$custom-control-indicator-size: 1.25rem;
+
 // stylelint-disable
 $theme-colors: () !default;
 $theme-colors: map-merge((
index 98be0ff..026eab3 100644 (file)
@@ -5060,7 +5060,7 @@ p.arrow_button input[type="button"],
   position: relative;
   display: block;
   min-height: 1.40625rem;
-  padding-left: 1.5rem; }
+  padding-left: 1.75rem; }
 
 .custom-control-inline {
   display: inline-flex;
@@ -5093,22 +5093,22 @@ p.arrow_button input[type="button"],
   vertical-align: top; }
   .custom-control-label::before {
     position: absolute;
-    top: 0.203125rem;
-    left: -1.5rem;
+    top: 0.078125rem;
+    left: -1.75rem;
     display: block;
-    width: 1rem;
-    height: 1rem;
+    width: 1.25rem;
+    height: 1.25rem;
     pointer-events: none;
     content: "";
     background-color: #fff;
     border: #adb5bd solid 1px; }
   .custom-control-label::after {
     position: absolute;
-    top: 0.203125rem;
-    left: -1.5rem;
+    top: 0.078125rem;
+    left: -1.75rem;
     display: block;
-    width: 1rem;
-    height: 1rem;
+    width: 1.25rem;
+    height: 1.25rem;
     content: "";
     background: no-repeat 50% / 50% 50%; }
 
@@ -5138,26 +5138,26 @@ p.arrow_button input[type="button"],
   background-color: rgba(17, 119, 209, 0.5); }
 
 .custom-switch {
-  padding-left: 2.25rem; }
+  padding-left: 2.6875rem; }
   .custom-switch .custom-control-label::before {
-    left: -2.25rem;
-    width: 1.75rem;
+    left: -2.6875rem;
+    width: 2.1875rem;
     pointer-events: all;
-    border-radius: 0.5rem; }
+    border-radius: 0.625rem; }
   .custom-switch .custom-control-label::after {
-    top: calc(0.203125rem + 2px);
-    left: calc(-2.25rem + 2px);
-    width: calc(1rem - 4px);
-    height: calc(1rem - 4px);
+    top: calc(0.078125rem + 2px);
+    left: calc(-2.6875rem + 2px);
+    width: calc(1.25rem - 4px);
+    height: calc(1.25rem - 4px);
     background-color: #adb5bd;
-    border-radius: 0.5rem;
+    border-radius: 0.625rem;
     transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
     @media (prefers-reduced-motion: reduce) {
       .custom-switch .custom-control-label::after {
         transition: none; } }
   .custom-switch .custom-control-input:checked ~ .custom-control-label::after {
     background-color: #fff;
-    transform: translateX(0.75rem); }
+    transform: translateX(0.9375rem); }
   .custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {
     background-color: rgba(17, 119, 209, 0.5); }
 
@@ -11407,74 +11407,6 @@ div.editor_atto_toolbar button .icon {
 .dir-ltr .dir-ltr-hide {
   display: none; }
 
-.switch {
-  position: relative;
-  display: inline-block; }
-  .switch input {
-    float: left;
-    width: 1px;
-    transform: translateX(1px);
-    padding: 0;
-    margin: 0;
-    opacity: 0;
-    line-height: 1.25rem; }
-    .switch input + label {
-      position: relative;
-      min-height: 1.25rem;
-      min-width: 2.5rem;
-      line-height: 1.25rem;
-      border-radius: 1.25rem;
-      display: inline-block;
-      cursor: pointer;
-      outline: none;
-      user-select: none;
-      padding-left: 3rem; }
-    .switch input + label::before,
-    .switch input + label::after {
-      content: '';
-      position: absolute;
-      left: 0;
-      bottom: 0;
-      display: block; }
-    .switch input + label::before {
-      right: 0;
-      height: 1rem;
-      width: 2.5rem;
-      top: calc(50% - 0.5rem);
-      background-color: #dee2e6;
-      border-radius: 1.25rem;
-      transition: 0.2s all; }
-    .switch input + label::after {
-      left: 0;
-      width: 1.25rem;
-      height: 1.25rem;
-      top: calc(50% - 0.625rem);
-      border-radius: 50%;
-      background-color: #fff;
-      transition: 0.2s all;
-      box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); }
-    .switch input:checked + label::before {
-      background-color: rgba(17, 119, 209, 0.4); }
-    .switch input:checked + label::after {
-      margin-left: 1.25rem;
-      background-color: #1177d1; }
-    .switch input:focus + label::before {
-      outline: none; }
-    .switch input:focus + label::after {
-      outline: none;
-      box-shadow: 0 0 0 0.4rem rgba(17, 119, 209, 0.25); }
-    .switch input:disabled + label {
-      color: #868e96;
-      cursor: not-allowed; }
-    .switch input:disabled + label::before {
-      background-color: #e9ecef; }
-    .switch input:disabled + label::after {
-      background-color: #868e96; }
-  .switch.sr-only-label input + label {
-    text-indent: -9999px;
-    margin-bottom: 0;
-    padding-left: 0; }
-
 .paged-content-page-container {
   min-height: 3.125rem; }
 
index 18e3946..4a592a1 100644 (file)
@@ -11662,74 +11662,6 @@ div.editor_atto_toolbar button .icon {
 .dir-ltr .dir-ltr-hide {
   display: none; }
 
-.switch {
-  position: relative;
-  display: inline-block; }
-  .switch input {
-    float: left;
-    width: 1px;
-    transform: translateX(1px);
-    padding: 0;
-    margin: 0;
-    opacity: 0;
-    line-height: 1.25rem; }
-    .switch input + label {
-      position: relative;
-      min-height: 1.25rem;
-      min-width: 2.5rem;
-      line-height: 1.25rem;
-      border-radius: 1.25rem;
-      display: inline-block;
-      cursor: pointer;
-      outline: none;
-      user-select: none;
-      padding-left: 3rem; }
-    .switch input + label::before,
-    .switch input + label::after {
-      content: '';
-      position: absolute;
-      left: 0;
-      bottom: 0;
-      display: block; }
-    .switch input + label::before {
-      right: 0;
-      height: 1rem;
-      width: 2.5rem;
-      top: calc(50% - 0.5rem);
-      background-color: #dee2e6;
-      border-radius: 1.25rem;
-      transition: 0.2s all; }
-    .switch input + label::after {
-      left: 0;
-      width: 1.25rem;
-      height: 1.25rem;
-      top: calc(50% - 0.625rem);
-      border-radius: 50%;
-      background-color: #fff;
-      transition: 0.2s all;
-      box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); }
-    .switch input:checked + label::before {
-      background-color: rgba(17, 119, 209, 0.4); }
-    .switch input:checked + label::after {
-      margin-left: 1.25rem;
-      background-color: #1177d1; }
-    .switch input:focus + label::before {
-      outline: none; }
-    .switch input:focus + label::after {
-      outline: none;
-      box-shadow: 0 0 0 0.4rem rgba(17, 119, 209, 0.25); }
-    .switch input:disabled + label {
-      color: #868e96;
-      cursor: not-allowed; }
-    .switch input:disabled + label::before {
-      background-color: #e9ecef; }
-    .switch input:disabled + label::after {
-      background-color: #868e96; }
-  .switch.sr-only-label input + label {
-    text-indent: -9999px;
-    margin-bottom: 0;
-    padding-left: 0; }
-
 .paged-content-page-container {
   min-height: 3.125rem; }