mumuki-laboratory 7.10.5 → 7.12.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) 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 +163 -0
  7. data/app/assets/javascripts/mumuki_laboratory/application/kids.js +171 -333
  8. data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +159 -0
  9. data/app/assets/javascripts/mumuki_laboratory/application/mu-modal-carrousel.js +63 -0
  10. data/app/assets/javascripts/mumuki_laboratory/application/number-counter.js +18 -0
  11. data/app/assets/javascripts/mumuki_laboratory/application/primary.js +258 -0
  12. data/app/assets/javascripts/mumuki_laboratory/application/profile.js +31 -16
  13. data/app/assets/javascripts/mumuki_laboratory/application/submission.js +1 -0
  14. data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +19 -2
  15. data/app/assets/stylesheets/mumuki_laboratory/application/_errors.scss +1 -3
  16. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +3 -1
  17. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_avatar.scss +21 -0
  18. data/app/assets/stylesheets/mumuki_laboratory/application/modules/{_chapter_show.scss → _content_show.scss} +0 -0
  19. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids_results.scss +117 -0
  20. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kindergarten.scss +335 -12
  21. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_medal.scss +48 -0
  22. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +44 -0
  23. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +40 -3
  24. data/app/controllers/application_controller.rb +15 -8
  25. data/app/controllers/book_discussions_controller.rb +4 -0
  26. data/app/controllers/users_controller.rb +8 -2
  27. data/app/helpers/avatar_helper.rb +11 -3
  28. data/app/helpers/contextualization_result_helper.rb +9 -1
  29. data/app/helpers/gamification_helper.rb +5 -0
  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/_contextualization_results_container.html.erb +9 -0
  42. data/app/views/exercise_solutions/_kids_level_up.html.erb +11 -0
  43. data/app/views/exercise_solutions/_kids_results.html.erb +1 -1
  44. data/app/views/exercise_solutions/_results_title.html.erb +5 -0
  45. data/app/views/exercises/show.html.erb +4 -0
  46. data/app/views/invitations/_invitation_form.html.erb +1 -0
  47. data/app/views/layouts/_discussions.html.erb +4 -0
  48. data/app/views/layouts/_error.html.erb +3 -6
  49. data/app/views/layouts/_guide.html.erb +10 -3
  50. data/app/views/layouts/_kindergarten.html.erb +38 -0
  51. data/app/views/layouts/_main.html.erb +3 -1
  52. data/app/views/layouts/_organization_chooser.html.erb +0 -7
  53. data/app/views/layouts/_terms_acceptance_disclaimer.html.erb +6 -0
  54. data/app/views/layouts/application.html.erb +10 -3
  55. data/app/views/layouts/exercise_inputs/layouts/_input_kindergarten.html.erb +27 -27
  56. data/app/views/layouts/modals/_guide_corollary.html.erb +10 -1
  57. data/app/views/layouts/modals/_kids_context.html.erb +1 -1
  58. data/app/views/layouts/modals/_kids_results.html.erb +16 -6
  59. data/app/views/layouts/modals/_kindergarten_context.html.erb +30 -0
  60. data/app/views/layouts/modals/_kindergarten_results.html.erb +36 -0
  61. data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +27 -0
  62. data/app/views/layouts/modals/_level_up.html.erb +27 -0
  63. data/app/views/users/_avatar_list.html.erb +6 -2
  64. data/app/views/users/_edit_user_form.html.erb +9 -4
  65. data/app/views/users/_term.html.erb +10 -0
  66. data/app/views/users/_user_form.html.erb +17 -3
  67. data/app/views/users/terms.html.erb +18 -0
  68. data/config/routes.rb +2 -0
  69. data/lib/mumuki/laboratory.rb +1 -1
  70. data/lib/mumuki/laboratory/controllers/current_organization.rb +1 -1
  71. data/lib/mumuki/laboratory/controllers/results_rendering.rb +4 -2
  72. data/lib/mumuki/laboratory/locales/en.yml +21 -5
  73. data/lib/mumuki/laboratory/locales/es-CL.yml +10 -4
  74. data/lib/mumuki/laboratory/locales/es.yml +22 -6
  75. data/lib/mumuki/laboratory/locales/pt.yml +21 -5
  76. data/lib/mumuki/laboratory/version.rb +1 -1
  77. data/spec/capybara_helper.rb +99 -0
  78. data/spec/controllers/exercise_solutions_controller_spec.rb +3 -4
  79. data/spec/dummy/db/schema.rb +37 -1
  80. data/spec/dummy/public/medal/outline.svg +1089 -0
  81. data/spec/features/choose_organization_spec.rb +12 -30
  82. data/spec/features/disable_user_flow_spec.rb +3 -5
  83. data/spec/features/disabled_organization_flow_spec.rb +9 -14
  84. data/spec/features/exercise_flow_spec.rb +2 -2
  85. data/spec/features/guide_reset_spec.rb +1 -1
  86. data/spec/features/guides_flow_spec.rb +1 -1
  87. data/spec/features/home_private_flow_spec.rb +1 -3
  88. data/spec/features/home_public_flow_spec.rb +6 -12
  89. data/spec/features/invitations_flow_spec.rb +2 -2
  90. data/spec/features/login_flow_spec.rb +2 -2
  91. data/spec/features/not_found_private_flow_spec.rb +4 -4
  92. data/spec/features/not_found_public_flow_spec.rb +1 -6
  93. data/spec/features/profile_flow_spec.rb +1 -1
  94. data/spec/helpers/page_title_helper_spec.rb +3 -3
  95. data/spec/javascripts/editors-spec.js +23 -0
  96. data/spec/javascripts/gamification-spec.js +58 -0
  97. data/spec/javascripts/submissions-store-spec.js +139 -6
  98. data/spec/spec_helper.rb +2 -0
  99. data/spec/teaspoon_env.rb +24 -6
  100. metadata +137 -98
@@ -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);
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,14 @@
1
+ @mixin full-size-character {
2
+ width: 100%;
3
+ height: 100%;
4
+ img {
5
+ width: 100%;
6
+ height: 100%;
7
+ object-position: center;
8
+ object-fit: contain;
9
+ }
10
+ }
11
+
1
12
  @each $class in success, warning, danger, broken {
2
13
  .mu-kids-callout-#{$class} {
3
14
  h4 {
@@ -47,3 +58,109 @@ $capital-animation-width: 135px;
47
58
  }
48
59
  }
49
60
 
61
+ .mu-kids-modal-border {
62
+
63
+ .modal-dialog {
64
+
65
+ height: 100vh;
66
+ width: 100vw;
67
+ margin: 0;
68
+
69
+ .modal-content {
70
+
71
+ position: absolute;
72
+
73
+ $width-lg: 800px;
74
+
75
+ width: $width-lg;
76
+
77
+ top: 60px;
78
+ left: calc(50% - #{$width-lg} / 2);
79
+
80
+ @media (max-width: $width-lg + 30px) {
81
+ width: calc(100vw - 30px);
82
+ }
83
+
84
+ $border-width: 16px;
85
+ border-width: $border-width;
86
+ border-style: solid;
87
+ border-color: $mu-color-link;
88
+ border-radius: $border-width;
89
+ box-shadow: none;
90
+
91
+ .modal-body {
92
+ div, p {
93
+ height: 100%;
94
+ .mu-kids-results-carrousel,
95
+ .mu-kindergarten-context-image-slides {
96
+ > :not(.active) {
97
+ display: none;
98
+ }
99
+ }
100
+ }
101
+ .mu-level p {
102
+ height: unset;
103
+ }
104
+ }
105
+
106
+ .mu-kids-modal-button {
107
+ $diameter: 64px;
108
+ position: absolute;
109
+ border-radius: 50%;
110
+ height: $diameter;
111
+ width: $diameter;
112
+ color: white;
113
+ font-weight: bold;
114
+ border: none;
115
+ padding: 0;
116
+ background: $mu-color-link;
117
+ &.mu-next,
118
+ &.mu-close {
119
+ top: - $diameter / 2 - $border-width / 2;
120
+ right: - $diameter / 2 - $border-width / 2;
121
+ }
122
+ &.mu-previous {
123
+ top: - $diameter / 2 - $border-width / 2;
124
+ left: - $diameter / 2 - $border-width / 2;
125
+ }
126
+ }
127
+
128
+ $mu-statuses-colors: (
129
+ 'broken': $mu-color-broken,
130
+ 'danger': $mu-color-danger,
131
+ 'success': $mu-color-success,
132
+ 'warning': $mu-color-warning,
133
+ 'passed': $mu-color-success,
134
+ 'passed-with-warnings': $mu-color-warning,
135
+ 'failed': $mu-color-danger,
136
+ 'errored': $mu-color-broken,
137
+ 'aborted': $mu-color-broken,
138
+ 'pending': $mu-color-info
139
+ );
140
+
141
+ @each $class, $color in $mu-statuses-colors {
142
+ &.#{$class} {
143
+ border-color: $color;
144
+ .mu-kids-modal-button {
145
+ background: $color;
146
+ }
147
+ }
148
+ .mu-kids-character.kindergarten {
149
+ @include full-size-character;
150
+ }
151
+
152
+ .submission-results.kindergarten {
153
+ width: 100%;
154
+ height: 100%;
155
+ .mu-kids-callout-#{$class},
156
+ p {
157
+ display: none;
158
+ }
159
+ .mu-kids-default-#{$class} {
160
+ @include full-size-character;
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
@@ -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,323 @@
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;
53
87
  }
54
88
  }
55
89
 
90
+ .modal-content.kindergarten {
91
+ $width-lg: 800px;
92
+ $height-lg: $width-lg * 0.625;
93
+
94
+ width: $width-lg;
95
+ height: $height-lg;
96
+
97
+ top: calc(50vh - #{$height-lg} / 2);
98
+
99
+ @media (orientation: landscape) and (max-height: $height-lg + 50px) {
100
+ $height-sm: 85vh;
101
+ $width-sm: $height-sm / 0.625;
102
+
103
+ width: $width-sm;
104
+ height: $height-sm;
105
+
106
+ top: calc(50vh - #{$height-sm} / 2);
107
+ left: calc(50vw - #{$width-sm} / 2);
108
+ }
109
+
110
+ @media (orientation: portrait) {
111
+ $height-sm: 85vh;
112
+ $width-sm: 85vw;
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
+ .modal-header,
122
+ .modal-footer {
123
+ text-align: center;
124
+ text-transform: uppercase;
125
+ }
126
+
127
+ .modal-body.mu-kids-context-body {
128
+ height: 100%;
129
+ div img, p img {
130
+ width: 100%;
131
+ height: 100%;
132
+ object-position: center;
133
+ object-fit: contain;
134
+ }
135
+ }
136
+ }
137
+
138
+ #kids-results.mu-kids-modal-border {
139
+ .modal-body{
140
+ height: calc(100% - #{$modal-header-height} - #{$modal-footer-height});
141
+ }
142
+ }
143
+
144
+ #kids-results-aborted.mu-kids-modal-border {
145
+ .modal-content.kindergarten {
146
+ .modal-body {
147
+ height: calc(100% - #{$modal-header-height});
148
+ }
149
+
150
+ h4.modal-header {
151
+ margin: 0;
152
+ }
153
+ }
154
+ }
155
+
156
+ $bubble-border-width: 3px;
157
+ $bubble-height: 90px;
158
+ $bubble-border: $bubble-border-width solid $kids-speech-border-color;
159
+ $bubble-ballon-size: 24px;
160
+
161
+ $bubble-background-color: white;
162
+ $bubble-padding: 30px;
163
+
164
+ .mu-kindergarten-header {
165
+ @include display-flex(row nowrap, flex-start, flex-start);
166
+
167
+ align-self: flex-start;
168
+
169
+ width: 100%;
170
+
171
+ .mu-kindergarten-character {
172
+ @include display-flex(row nowrap, flex-start, flex-start);
173
+
174
+ margin-right: 15px;
175
+
176
+ width: 50%;
177
+
178
+ $bubble-border-width: 3px;
179
+ $bubble-height: 90px;
180
+ $bubble-border: $bubble-border-width solid $kids-speech-border-color;
181
+ $bubble-ballon-size: 24px;
182
+
183
+ $bubble-background-color: white;
184
+ $bubble-padding: 30px;
185
+
186
+ .mu-kindergarten-character-speech-bubble {
187
+ @include display-flex(row, flex-start, center);
188
+ position: relative;
189
+
190
+ padding: $bubble-padding;
191
+ padding-right: $bubble-height / 2 + $bubble-padding;
192
+
193
+ color: #333;
194
+ border-radius: 10px;
195
+ background: white;
196
+ border: $bubble-border;
197
+ height: $bubble-height;
198
+ min-height: $bubble-height;
199
+ max-height: $bubble-height;
200
+
201
+ width: 100%;
202
+ max-width: 100%;
203
+
204
+ margin-top: 10px;
205
+
206
+ p {
207
+ margin: 0;
208
+ }
209
+
210
+ &:before {
211
+ content: "";
212
+ position: absolute;
213
+ bottom: -20px;
214
+ top: $bubble-height / 2 - $bubble-ballon-size / 2;
215
+ left: -$bubble-ballon-size / 2;
216
+ width: $bubble-ballon-size;
217
+ height: $bubble-ballon-size;
218
+ background: white;
219
+ border: $bubble-border;
220
+ border-left-color: $bubble-background-color;
221
+ border-top-color: $bubble-background-color;
222
+ transform: rotate(135deg);
223
+ border-radius: 50%;
224
+ }
225
+ }
226
+
227
+ .mu-kindergarten-buttons {
228
+ display: flex;
229
+ flex-flow: column;
230
+ position: absolute;
231
+ top: -$bubble-border-width;
232
+ right: -$bubble-border-width;
233
+ height: calc(100% + #{$bubble-border-width} * 3);
234
+ border-radius: 10px;
235
+
236
+ .mu-kindergarten-show-context,
237
+ .mu-kindergarten-play-description {
238
+ border: $bubble-border;
239
+ height: calc(50% - #{$bubble-border-width} / 2);
240
+ width: $bubble-height / 2;
241
+ }
242
+
243
+ .mu-kindergarten-show-context {
244
+ border-top-right-radius: 10px;
245
+ border-bottom-width: $bubble-border-width * 2/3;
246
+ }
247
+
248
+ .mu-kindergarten-play-description {
249
+ border-bottom-right-radius: 10px;
250
+ border-top-width: $bubble-border-width * 2/3;
251
+ }
252
+
253
+ .mu-kindergarten-button-image {
254
+ width: 100%;
255
+ }
256
+
257
+ }
258
+ }
259
+
260
+ .mu-kindergarten-hint {
261
+
262
+ $light-bubble-color: #FAD59F;
263
+ $light-bubble-border: $bubble-border-width solid $light-bubble-color;
264
+
265
+ @include display-flex(row-reverse nowrap, flex-start, flex-start);
266
+
267
+ width: 50%;
268
+ margin-left: 15px;
269
+
270
+ margin-top: 10px;
271
+
272
+ button {
273
+ background: none;
274
+ border: none;
275
+ outline: none;
276
+ }
56
277
 
278
+ .mu-hint-light {
279
+ $light-height: 80px;
280
+ padding-left: 15px;
281
+
282
+ &.off {
283
+ height: $light-height * 0.75;
284
+ margin-right: 11px;
285
+ margin-top: 21px;
286
+ }
287
+ &.on {
288
+ cursor: pointer;
289
+ height: $light-height;
290
+ &:hover {
291
+ filter: brightness(1.15);
292
+ }
293
+ }
294
+ }
295
+
296
+ .mu-kindergarten-light-speech-bubble {
297
+ @include display-flex(column, center, flex-start);
298
+
299
+ position: relative;
300
+
301
+ padding: $bubble-padding;
302
+
303
+ color: #333;
304
+ border-radius: 10px;
305
+ background: $light-bubble-color;
306
+ border: $light-bubble-border;
307
+ min-height: $bubble-height;
308
+ z-index: 1;
309
+
310
+ width: 75%;
311
+ max-width: 100%;
312
+
313
+ p {
314
+ margin: 0;
315
+ text-align: center;
316
+ }
317
+
318
+ &:after {
319
+ content: "";
320
+ position: absolute;
321
+ bottom: -20px;
322
+ top: $bubble-height / 2 - $bubble-ballon-size / 2;
323
+ right: -$bubble-ballon-size / 2;
324
+ width: $bubble-ballon-size;
325
+ height: $bubble-ballon-size;
326
+ background: $light-bubble-color;
327
+ border: $light-bubble-border;
328
+ border-radius: 50%;
329
+ }
330
+
331
+ .mu-kindergarten-exercise-hint {
332
+ width: 100%;
333
+ }
334
+
335
+ .mu-kindergarten-hint-media {
336
+
337
+ @include display-flex(column, center, center);
338
+
339
+ background: white;
340
+ width: calc(100% + #{$bubble-padding} * 10/6);
341
+ margin: $bubble-padding (-$bubble-padding * 5/6) (-$bubble-padding * 5/6) (-$bubble-padding * 5/6);
342
+ padding: $bubble-padding * 5/6;
343
+
344
+ &.closed {
345
+ display: none;
346
+ }
347
+
348
+ .media-object {
349
+ height: 100%;
350
+ width: 100%;
351
+ object-fit: cover;
352
+ }
353
+ }
354
+
355
+ .expand-or-collapse-hint-media {
356
+ $button-width: 60px;
357
+
358
+ position: absolute;
359
+ width: $button-width;
360
+ height: $button-width / 2;
361
+ bottom: 3px;
362
+ left: calc(50% - #{$button-width / 2});
363
+
364
+ .fa-caret-down {
365
+ color: white;
366
+ }
367
+
368
+ .fa-caret-up {
369
+ color: $light-bubble-color;
370
+ }
371
+ }
372
+
373
+ &:not(.open) {
374
+ display: none;
375
+ }
376
+ }
377
+
378
+ }
379
+ }