mumuki-laboratory 7.10.5 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -7
  3. data/Rakefile +9 -2
  4. data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +26 -5
  5. data/app/assets/javascripts/mumuki_laboratory/application/characters.js +3 -1
  6. data/app/assets/javascripts/mumuki_laboratory/application/gamification.js +85 -0
  7. data/app/assets/javascripts/mumuki_laboratory/application/kids.js +160 -334
  8. data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +200 -0
  9. data/app/assets/javascripts/mumuki_laboratory/application/primary.js +257 -0
  10. data/app/assets/javascripts/mumuki_laboratory/application/profile.js +31 -16
  11. data/app/assets/javascripts/mumuki_laboratory/application/submission.js +1 -0
  12. data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +19 -2
  13. data/app/assets/stylesheets/mumuki_laboratory/application/_errors.scss +1 -3
  14. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +3 -1
  15. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_avatar.scss +21 -0
  16. data/app/assets/stylesheets/mumuki_laboratory/application/modules/{_chapter_show.scss → _content_show.scss} +0 -0
  17. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kindergarten.scss +421 -12
  18. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_medal.scss +48 -0
  19. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +44 -0
  20. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +9 -0
  21. data/app/controllers/api/courses_controller.rb +1 -2
  22. data/app/controllers/api/organizations_controller.rb +2 -3
  23. data/app/controllers/api/users_controller.rb +2 -4
  24. data/app/controllers/application_controller.rb +15 -8
  25. data/app/controllers/book_discussions_controller.rb +4 -0
  26. data/app/controllers/invitations_controller.rb +1 -2
  27. data/app/controllers/users_controller.rb +8 -2
  28. data/app/helpers/avatar_helper.rb +11 -3
  29. data/app/helpers/contextualization_result_helper.rb +9 -1
  30. data/app/helpers/kindergarten_helper.rb +5 -0
  31. data/app/helpers/links_helper.rb +8 -0
  32. data/app/helpers/medal_helper.rb +36 -0
  33. data/app/helpers/open_graph_helper.rb +2 -2
  34. data/app/helpers/organization_list_helper.rb +1 -1
  35. data/app/helpers/overlapped_buttons_helper.rb +1 -1
  36. data/app/helpers/page_title_helper.rb +2 -2
  37. data/app/helpers/profile_helper.rb +9 -1
  38. data/app/views/book/_header.html.erb +17 -0
  39. data/app/views/book/show.html.erb +1 -18
  40. data/app/views/discussions/terms.html.erb +10 -0
  41. data/app/views/exercise_solutions/_kids_results.html.erb +1 -1
  42. data/app/views/exercises/show.html.erb +1 -0
  43. data/app/views/invitations/_invitation_form.html.erb +1 -0
  44. data/app/views/layouts/_discussions.html.erb +4 -0
  45. data/app/views/layouts/_error.html.erb +3 -6
  46. data/app/views/layouts/_guide.html.erb +10 -3
  47. data/app/views/layouts/_kindergarten.html.erb +38 -0
  48. data/app/views/layouts/_main.html.erb +3 -1
  49. data/app/views/layouts/_organization_chooser.html.erb +0 -7
  50. data/app/views/layouts/_terms_acceptance_disclaimer.html.erb +6 -0
  51. data/app/views/layouts/application.html.erb +3 -2
  52. data/app/views/layouts/exercise_inputs/layouts/_input_kindergarten.html.erb +27 -27
  53. data/app/views/layouts/modals/_guide_corollary.html.erb +9 -0
  54. data/app/views/layouts/modals/_kindergarten_context.html.erb +30 -0
  55. data/app/views/layouts/modals/_kindergarten_results.html.erb +23 -0
  56. data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +27 -0
  57. data/app/views/users/_avatar_list.html.erb +6 -2
  58. data/app/views/users/_edit_user_form.html.erb +9 -4
  59. data/app/views/users/_term.html.erb +10 -0
  60. data/app/views/users/_user_form.html.erb +5 -1
  61. data/app/views/users/terms.html.erb +18 -0
  62. data/config/routes.rb +2 -0
  63. data/lib/mumuki/laboratory.rb +1 -1
  64. data/lib/mumuki/laboratory/controllers/current_organization.rb +1 -1
  65. data/lib/mumuki/laboratory/controllers/results_rendering.rb +3 -2
  66. data/lib/mumuki/laboratory/events/events.rb +0 -24
  67. data/lib/mumuki/laboratory/locales/en.yml +16 -5
  68. data/lib/mumuki/laboratory/locales/es-CL.yml +5 -4
  69. data/lib/mumuki/laboratory/locales/es.yml +17 -6
  70. data/lib/mumuki/laboratory/locales/pt.yml +16 -5
  71. data/lib/mumuki/laboratory/version.rb +1 -1
  72. data/spec/capybara_helper.rb +99 -0
  73. data/spec/controllers/exercise_solutions_controller_spec.rb +3 -4
  74. data/spec/dummy/db/schema.rb +37 -1
  75. data/spec/dummy/public/medal/outline.svg +1089 -0
  76. data/spec/features/choose_organization_spec.rb +12 -30
  77. data/spec/features/disable_user_flow_spec.rb +3 -5
  78. data/spec/features/disabled_organization_flow_spec.rb +9 -14
  79. data/spec/features/exercise_flow_spec.rb +2 -2
  80. data/spec/features/guide_reset_spec.rb +1 -1
  81. data/spec/features/guides_flow_spec.rb +1 -1
  82. data/spec/features/home_private_flow_spec.rb +1 -3
  83. data/spec/features/home_public_flow_spec.rb +6 -12
  84. data/spec/features/invitations_flow_spec.rb +2 -2
  85. data/spec/features/login_flow_spec.rb +2 -2
  86. data/spec/features/not_found_private_flow_spec.rb +4 -4
  87. data/spec/features/not_found_public_flow_spec.rb +1 -6
  88. data/spec/features/profile_flow_spec.rb +1 -1
  89. data/spec/helpers/page_title_helper_spec.rb +3 -3
  90. data/spec/javascripts/editors-spec.js +23 -0
  91. data/spec/javascripts/gamification-spec.js +58 -0
  92. data/spec/javascripts/submissions-store-spec.js +139 -6
  93. data/spec/spec_helper.rb +2 -0
  94. data/spec/teaspoon_env.rb +24 -6
  95. metadata +41 -7
@@ -1,12 +1,13 @@
1
1
  mumuki.load(function() {
2
2
  let $userForm = $("#mu-user-form");
3
3
  let $userAvatar = $('#mu-user-avatar');
4
- let $editButton = $('#mu-edit-profile-btn');
4
+ let $editButton = $('.mu-edit-profile-btn');
5
5
  let $avatarPicker = $('#mu-avatar-picker');
6
- let $avatarItem = $('.mu-avatar-item');
6
+ let $avatarItem = $('.mu-avatar-item:not(.mu-locked)');
7
7
 
8
8
  let userImage = "";
9
9
  let avatarId = "";
10
+ let avatarType = "";
10
11
 
11
12
  let originalData = $userForm.serialize();
12
13
  let originalProfilePicture = $userAvatar.attr('src');
@@ -15,14 +16,18 @@ mumuki.load(function() {
15
16
  toggleEditButtonIfThereAreChanges();
16
17
  });
17
18
 
18
- $avatarItem.on('click', function() {
19
- $userAvatar.attr('src', $(this).attr('src'));
20
- $avatarPicker.modal('hide');
19
+ $avatarItem.on('keypress click', function(e) {
20
+ onClickOrSpacebarOrEnter($(this), e, function() {
21
+ $userAvatar.attr('src', $(this).attr('src'));
22
+ $avatarPicker.modal('hide');
21
23
 
22
- const clickedAvatarId = $(this).attr('mu-avatar-id');
23
- avatarId = clickedAvatarId || "";
24
+ const clickedAvatarId = $(this).attr('mu-avatar-id');
25
+ const clickedAvatarType = $(this).attr('type');
26
+ avatarId = clickedAvatarId || "";
27
+ avatarType = clickedAvatarType || "";
24
28
 
25
- toggleEditButtonIfThereAreChanges();
29
+ toggleEditButtonIfThereAreChanges();
30
+ });
26
31
  });
27
32
 
28
33
  function toggleEditButtonIfThereAreChanges() {
@@ -41,18 +46,20 @@ mumuki.load(function() {
41
46
 
42
47
  const avatarChanged = () => $userAvatar.attr('src') !== originalProfilePicture;
43
48
 
44
- $('#mu-user-image').on('click', function(){
45
- userImage = $userAvatar.attr('src');
49
+ $('#mu-user-image').on('keypress click', function(e){
50
+ onClickOrSpacebarOrEnter($(this), e, function() {
51
+ userImage = $userAvatar.attr('src');
52
+ });
46
53
  });
47
54
 
48
55
  $userForm.on('submit', function(){
49
56
  if (userImage) {
50
57
  setImageUrl($(this), userImage);
51
- setAvatarId($(this), "");
58
+ setAvatarIdAndType($(this), "", "");
52
59
  }
53
60
 
54
61
  if (avatarId) {
55
- setAvatarId($(this), avatarId);
62
+ setAvatarIdAndType($(this), avatarId, avatarType);
56
63
  }
57
64
  });
58
65
 
@@ -60,12 +67,20 @@ mumuki.load(function() {
60
67
  form.append(`<input type="hidden" name="user[image_url]" value="${url}"/>`);
61
68
  }
62
69
 
63
- function setAvatarId(form, id) {
64
- form.append(`<input type="hidden" name="user[avatar_id]" value=${id}/>`);
70
+ function setAvatarIdAndType(form, id, type) {
71
+ form.append(`<input type="hidden" name="user[avatar_id]" value="${id}"/>`);
72
+ form.append(`<input type="hidden" name="user[avatar_type]" value="${type}"/>`);
65
73
  }
66
74
 
67
- $("#mu-edit-avatar-icon").on('click', function(){
68
- $avatarPicker.modal();
75
+ $("#mu-edit-avatar-icon").on('keypress click', function(e) {
76
+ onClickOrSpacebarOrEnter($(this), e, function() {
77
+ $avatarPicker.modal();
78
+ });
69
79
  });
70
80
 
81
+ function onClickOrSpacebarOrEnter(element, e, func) {
82
+ if (e.which === 13 || e.which === 32 || e.type === 'click') {
83
+ func.apply(element);
84
+ }
85
+ }
71
86
  });
@@ -26,6 +26,7 @@ mumuki.submission = (() => {
26
26
  this.submissionsResultsArea.html(data.html);
27
27
  data.status === 'aborted' ? this.error(submitButton) : submitButton.enable();
28
28
  mumuki.updateProgressBarAndShowModal(data);
29
+ mumuki.gamification._currentLevelProgression.setExpMessage(data.current_exp);
29
30
  }
30
31
  error(submitButton) {
31
32
  this.submissionsResultsArea.html('');
@@ -53,7 +53,7 @@ mumuki.SubmissionsStore = (() => {
53
53
  }
54
54
 
55
55
  /**
56
- * Extract the submission's solution content
56
+ * Extract the submission's solution content, expressed as a string
57
57
  *
58
58
  * @param {Submission} submission
59
59
  * @returns {string}
@@ -61,8 +61,13 @@ mumuki.SubmissionsStore = (() => {
61
61
  submissionSolutionContent(submission) {
62
62
  if (submission.solution) {
63
63
  return submission.solution.content;
64
- } else {
64
+ } else if (submission['solution[content]'] !== undefined) {
65
65
  return submission['solution[content]'];
66
+ } else {
67
+ return JSON.stringify(
68
+ Object
69
+ .entries(submission)
70
+ .filter(([key, _]) => key.startsWith('solution[content[')));
66
71
  }
67
72
  }
68
73
 
@@ -78,6 +83,10 @@ mumuki.SubmissionsStore = (() => {
78
83
  return this.submissionSolutionContent(one) === this.submissionSolutionContent(other);
79
84
  }
80
85
 
86
+ clear() {
87
+ window.localStorage.clear();
88
+ }
89
+
81
90
  // private API
82
91
 
83
92
  _asString(object) {
@@ -91,3 +100,11 @@ mumuki.SubmissionsStore = (() => {
91
100
 
92
101
  return SubmissionsStore;
93
102
  })();
103
+
104
+ mumuki.load(() => {
105
+ $('.mu-restart-guide').on("confirm:complete", (e) => {
106
+ if (e.detail[0]) {
107
+ mumuki.SubmissionsStore.clear();
108
+ }
109
+ })
110
+ })
@@ -13,9 +13,7 @@
13
13
  margin: 30px auto;
14
14
  max-height: 350px;
15
15
  &.error-code-img {
16
- margin-top: -80px;
17
- margin-left: 0;
18
- margin-bottom: 0;
16
+ margin: 0;
19
17
  min-height: 310px;
20
18
  max-height: 500px;
21
19
  width: calc(100%);
@@ -1,9 +1,9 @@
1
1
  @import "modules/avatar";
2
2
  @import "modules/book_header";
3
3
  @import "modules/breadcrumb";
4
- @import "modules/chapter_show";
5
4
  @import "modules/checkboxes";
6
5
  @import "modules/console";
6
+ @import "modules/content_show";
7
7
  @import "modules/datepicker";
8
8
  @import "modules/discussion";
9
9
  @import "modules/dropdown";
@@ -17,12 +17,14 @@
17
17
  @import "modules/kids";
18
18
  @import "modules/kindergarten";
19
19
  @import "modules/kids_results";
20
+ @import "modules/medal";
20
21
  @import "modules/modal";
21
22
  @import "modules/organization_chooser";
22
23
  @import "modules/overlap";
23
24
  @import "modules/popover";
24
25
  @import "modules/progress_bar";
25
26
  @import "modules/progress_listing";
27
+ @import "modules/terms";
26
28
  @import "modules/timer";
27
29
  @import "modules/upload";
28
30
  @import "modules/user_profile";
@@ -12,6 +12,16 @@
12
12
  position: relative;
13
13
  top: 100px;
14
14
  right: 15px;
15
+
16
+ &:hover {
17
+ outline: none;
18
+ opacity: 0.5;
19
+ }
20
+
21
+ &:focus {
22
+ outline: none;
23
+ opacity: 0.5;
24
+ }
15
25
  }
16
26
 
17
27
  .mu-avatar-list {
@@ -38,4 +48,15 @@
38
48
  box-shadow: -3px 3px 10px -3px $mu-color-primary;
39
49
  transform: scale(1.025);
40
50
  }
51
+
52
+ &:focus {
53
+ outline: none;
54
+ box-shadow: -3px 3px 10px -3px $mu-color-primary;
55
+ transform: scale(1.025);
56
+ }
57
+
58
+ &.mu-locked {
59
+ filter: grayscale(100%);
60
+ cursor: default;
61
+ }
41
62
  }
@@ -1,3 +1,6 @@
1
+ $modal-header-height: 95px;
2
+ $modal-footer-height: 95px;
3
+
1
4
  .mu-kids-exercise.mu-kindergarten {
2
5
 
3
6
  // layout
@@ -8,14 +11,29 @@
8
11
  .mu-kids-exercise-workspace {
9
12
  display: flex;
10
13
  flex-flow: row;
11
- height: calc(100% - #{$kids-characters-height});
14
+ height: calc(100% - #{$kids-characters-height} - 15px);
12
15
  width: 100%;
13
- }
14
16
 
15
- .mu-kids-single-state,
16
- .mu-kids-blocks {
17
- width: 50%;
18
- height: 100%
17
+ .mu-kids-single-state,
18
+ .mu-kids-blocks {
19
+ width: 50%;
20
+ height: 100%;
21
+ }
22
+
23
+ .mu-kids-blocks {
24
+ margin-right: 15px;
25
+ }
26
+
27
+ &.mu-full-workspace {
28
+ .mu-kids-single-state {
29
+ display: none
30
+ }
31
+ .mu-kids-blocks {
32
+ width: 100%;
33
+ height: 100%
34
+ }
35
+ }
36
+
19
37
  }
20
38
 
21
39
  .mu-kids-blocks {
@@ -39,18 +57,409 @@
39
57
  // no final state,
40
58
  // initial state fills its area
41
59
 
42
- .mu-kids-state.mu-state-initial {
43
- height: 100%;
44
- width: 100%;
60
+ .mu-kids-state {
61
+ &.mu-state-initial {
62
+ height: 100%;
63
+ width: 100%;
64
+ }
65
+ &.mu-state-final {
66
+ display: none;
67
+ }
68
+ .mu-kids-state-image {
69
+ padding: 30px;
70
+ img {
71
+ padding: 0;
72
+ border: 3px solid black;
73
+ border-radius: 30px;
74
+ }
75
+ }
45
76
  }
46
77
 
47
- .mu-kids-state.mu-state-final {
78
+ .mu-kids-compass-rose {
48
79
  display: none;
49
80
  }
81
+ }
50
82
 
51
- .mu-kids-compass-rose {
52
- display: none;
83
+ .mu-kindergarten.container-fluid {
84
+ .mu-kids-exercise-description,
85
+ .mu-kids-exercise-description-fixed {
86
+ padding: 0;
87
+ }
88
+ }
89
+
90
+ .mu-kindergarten-context {
91
+
92
+ .modal-dialog {
93
+
94
+ height: 100vh;
95
+ width: 100vw;
96
+ margin: 0;
97
+
98
+ .modal-content {
99
+ position: absolute;
100
+
101
+ $width-lg: 800px;
102
+ $height-lg: $width-lg * 0.625;
103
+
104
+ width: $width-lg;
105
+ height: $height-lg;
106
+
107
+ top: calc(50vh - #{$height-lg} / 2);
108
+ left: calc(50vw - #{$width-lg} / 2);
109
+
110
+ @media (orientation: landscape) and (max-height: $height-lg + 50px) {
111
+ $height-sm: 85vh;
112
+ $width-sm: $height-sm / 0.625;
113
+
114
+ width: $width-sm;
115
+ height: $height-sm;
116
+
117
+ top: calc(50vh - #{$height-sm} / 2);
118
+ left: calc(50vw - #{$width-sm} / 2);
119
+ }
120
+
121
+ @media (orientation: portrait) {
122
+ $height-sm: 85vh;
123
+ $width-sm: 85vw;
124
+
125
+ width: $width-sm;
126
+ height: $height-sm;
127
+
128
+ top: calc(50vh - #{$height-sm} / 2);
129
+ left: calc(50vw - #{$width-sm} / 2);
130
+ }
131
+
132
+ $border-width: 16px;
133
+ border-width: $border-width;
134
+ border-style: solid;
135
+ border-color: $mu-color-link;
136
+ border-radius: $border-width;
137
+ box-shadow: none;
138
+
139
+ .modal-header,
140
+ .modal-footer {
141
+ text-align: center;
142
+ text-transform: uppercase;
143
+ }
144
+
145
+ .modal-body {
146
+ height: 100%;
147
+ div, p {
148
+ height: 100%;
149
+ .mu-kindergarten-context-image-slides {
150
+ img:not(.active) {
151
+ display: none;
152
+ }
153
+ }
154
+ img {
155
+ width: 100%;
156
+ height: 100%;
157
+ object-position: center;
158
+ object-fit: contain;
159
+ }
160
+ }
161
+ }
162
+
163
+ .mu-kindergarten-modal-button {
164
+ $diameter: 64px;
165
+ position: absolute;
166
+ border-radius: 50%;
167
+ height: $diameter;
168
+ width: $diameter;
169
+ color: white;
170
+ font-weight: bold;
171
+ border: none;
172
+ padding: 0;
173
+ background: $mu-color-link;
174
+ &.mu-next,
175
+ &.mu-close {
176
+ top: - $diameter / 2 - $border-width / 2;
177
+ right: - $diameter / 2 - $border-width / 2;
178
+ }
179
+ &.mu-previous {
180
+ top: - $diameter / 2 - $border-width / 2;
181
+ left: - $diameter / 2 - $border-width / 2;
182
+ }
183
+ }
184
+
185
+ $mu-statuses-colors: (
186
+ 'broken': $mu-color-broken,
187
+ 'danger': $mu-color-danger,
188
+ 'success': $mu-color-success,
189
+ 'warning': $mu-color-warning,
190
+ 'passed': $mu-color-success,
191
+ 'passed-with-warnings': $mu-color-warning,
192
+ 'failed': $mu-color-danger,
193
+ 'errored': $mu-color-broken,
194
+ 'aborted': $mu-color-broken,
195
+ 'pending': $mu-color-info
196
+ );
197
+
198
+ @each $class, $color in $mu-statuses-colors {
199
+ &.#{$class} {
200
+ border-color: $color;
201
+ .mu-kindergarten-modal-button {
202
+ background: $color;
203
+ }
204
+ }
205
+ .submission-results {
206
+ width: 100%;
207
+ height: 100%;
208
+ .mu-kids-callout-#{$class},
209
+ p {
210
+ display: none;
211
+ }
212
+ .mu-kids-default-#{$class} {
213
+ width: 100%;
214
+ height: 100%;
215
+ img {
216
+ width: 100%;
217
+ height: 100%;
218
+ object-position: center;
219
+ object-fit: contain;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
53
225
  }
54
226
  }
55
227
 
228
+ #kids-results.mu-kindergarten-context {
229
+ .modal-body{
230
+ height: calc(100% - #{$modal-header-height} - #{$modal-footer-height});
231
+ }
232
+ }
233
+ #kids-results-aborted.mu-kindergarten-context {
234
+ .modal-body{
235
+ height: calc(100% - #{$modal-header-height});
236
+ }
237
+ h4.modal-header {
238
+ margin: 0;
239
+ }
240
+ }
241
+
242
+ $bubble-border-width: 3px;
243
+ $bubble-height: 90px;
244
+ $bubble-border: $bubble-border-width solid $kids-speech-border-color;
245
+ $bubble-ballon-size: 24px;
246
+
247
+ $bubble-background-color: white;
248
+ $bubble-padding: 30px;
249
+
250
+ .mu-kindergarten-header {
251
+ @include display-flex(row nowrap, flex-start, flex-start);
252
+
253
+ align-self: flex-start;
254
+
255
+ width: 100%;
256
+
257
+ .mu-kindergarten-character {
258
+ @include display-flex(row nowrap, flex-start, flex-start);
259
+
260
+ margin-right: 15px;
261
+
262
+ width: 50%;
263
+
264
+ $bubble-border-width: 3px;
265
+ $bubble-height: 90px;
266
+ $bubble-border: $bubble-border-width solid $kids-speech-border-color;
267
+ $bubble-ballon-size: 24px;
268
+
269
+ $bubble-background-color: white;
270
+ $bubble-padding: 30px;
271
+
272
+ .mu-kindergarten-character-speech-bubble {
273
+ @include display-flex(row, flex-start, center);
274
+ position: relative;
275
+
276
+ padding: $bubble-padding;
277
+ padding-right: $bubble-height / 2 + $bubble-padding;
278
+
279
+ color: #333;
280
+ border-radius: 10px;
281
+ background: white;
282
+ border: $bubble-border;
283
+ height: $bubble-height;
284
+ min-height: $bubble-height;
285
+ max-height: $bubble-height;
286
+
287
+ width: 100%;
288
+ max-width: 100%;
289
+
290
+ margin-top: 10px;
291
+
292
+ p {
293
+ margin: 0;
294
+ }
295
+
296
+ &:before {
297
+ content: "";
298
+ position: absolute;
299
+ bottom: -20px;
300
+ top: $bubble-height / 2 - $bubble-ballon-size / 2;
301
+ left: -$bubble-ballon-size / 2;
302
+ width: $bubble-ballon-size;
303
+ height: $bubble-ballon-size;
304
+ background: white;
305
+ border: $bubble-border;
306
+ border-left-color: $bubble-background-color;
307
+ border-top-color: $bubble-background-color;
308
+ transform: rotate(135deg);
309
+ border-radius: 50%;
310
+ }
311
+ }
312
+
313
+ .mu-kindergarten-buttons {
314
+ display: flex;
315
+ flex-flow: column;
316
+ position: absolute;
317
+ top: -$bubble-border-width;
318
+ right: -$bubble-border-width;
319
+ height: calc(100% + #{$bubble-border-width} * 3);
320
+ border-radius: 10px;
321
+
322
+ .mu-kindergarten-show-context,
323
+ .mu-kindergarten-play-description {
324
+ border: $bubble-border;
325
+ height: calc(50% - #{$bubble-border-width} / 2);
326
+ width: $bubble-height / 2;
327
+ }
328
+
329
+ .mu-kindergarten-show-context {
330
+ border-top-right-radius: 10px;
331
+ border-bottom-width: $bubble-border-width * 2/3;
332
+ }
333
+
334
+ .mu-kindergarten-play-description {
335
+ border-bottom-right-radius: 10px;
336
+ border-top-width: $bubble-border-width * 2/3;
337
+ }
338
+
339
+ .mu-kindergarten-button-image {
340
+ width: 100%;
341
+ }
342
+
343
+ }
344
+ }
345
+
346
+ .mu-kindergarten-hint {
347
+
348
+ $light-bubble-color: #FAD59F;
349
+ $light-bubble-border: $bubble-border-width solid $light-bubble-color;
350
+
351
+ @include display-flex(row-reverse nowrap, flex-start, flex-start);
352
+
353
+ width: 50%;
354
+ margin-left: 15px;
355
+
356
+ margin-top: 10px;
56
357
 
358
+ button {
359
+ background: none;
360
+ border: none;
361
+ outline: none;
362
+ }
363
+
364
+ .mu-hint-light {
365
+ $light-height: 80px;
366
+ padding-left: 15px;
367
+
368
+ &.off {
369
+ height: $light-height * 0.75;
370
+ margin-right: 11px;
371
+ margin-top: 21px;
372
+ }
373
+ &.on {
374
+ cursor: pointer;
375
+ height: $light-height;
376
+ &:hover {
377
+ filter: brightness(1.15);
378
+ }
379
+ }
380
+ }
381
+
382
+ .mu-kindergarten-light-speech-bubble {
383
+ @include display-flex(column, center, flex-start);
384
+
385
+ position: relative;
386
+
387
+ padding: $bubble-padding;
388
+
389
+ color: #333;
390
+ border-radius: 10px;
391
+ background: $light-bubble-color;
392
+ border: $light-bubble-border;
393
+ min-height: $bubble-height;
394
+ z-index: 1;
395
+
396
+ width: 75%;
397
+ max-width: 100%;
398
+
399
+ p {
400
+ margin: 0;
401
+ text-align: center;
402
+ }
403
+
404
+ &:after {
405
+ content: "";
406
+ position: absolute;
407
+ bottom: -20px;
408
+ top: $bubble-height / 2 - $bubble-ballon-size / 2;
409
+ right: -$bubble-ballon-size / 2;
410
+ width: $bubble-ballon-size;
411
+ height: $bubble-ballon-size;
412
+ background: $light-bubble-color;
413
+ border: $light-bubble-border;
414
+ border-radius: 50%;
415
+ }
416
+
417
+ .mu-kindergarten-exercise-hint {
418
+ width: 100%;
419
+ }
420
+
421
+ .mu-kindergarten-hint-media {
422
+
423
+ @include display-flex(column, center, center);
424
+
425
+ background: white;
426
+ width: calc(100% + #{$bubble-padding} * 10/6);
427
+ margin: $bubble-padding (-$bubble-padding * 5/6) (-$bubble-padding * 5/6) (-$bubble-padding * 5/6);
428
+ padding: $bubble-padding * 5/6;
429
+
430
+ &.closed {
431
+ display: none;
432
+ }
433
+
434
+ .media-object {
435
+ height: 100%;
436
+ width: 100%;
437
+ object-fit: cover;
438
+ }
439
+ }
440
+
441
+ .expand-or-collapse-hint-media {
442
+ $button-width: 60px;
443
+
444
+ position: absolute;
445
+ width: $button-width;
446
+ height: $button-width / 2;
447
+ bottom: 3px;
448
+ left: calc(50% - #{$button-width / 2});
449
+
450
+ .fa-caret-down {
451
+ color: white;
452
+ }
453
+
454
+ .fa-caret-up {
455
+ color: $light-bubble-color;
456
+ }
457
+ }
458
+
459
+ &:not(.open) {
460
+ display: none;
461
+ }
462
+ }
463
+
464
+ }
465
+ }