Skip to content

Commit edc231c

Browse files
authored
Add Dark Theme (and fix a few theming bugs) (#6343)
This adds a dark theme for micro:bit and fixes a few theming bugs along the way. While doing this work, I found a few places in the micro:bit styles.less that were hard-coded to light-theme-specific values. I themed them when I could and moved the rest into overrides.
1 parent 2047bab commit edc231c

File tree

5 files changed

+278
-24
lines changed

5 files changed

+278
-24
lines changed

theme/blockly-toolbox.less

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*******************************/
55

66
div.blocklyTreeRow {
7-
box-shadow: inset 0 -1px 0 0 #ecf0f1;
7+
box-shadow: inset 0 -1px 0 0 var(--pxt-target-stencil3);
88

99
margin-bottom: 0px !important;
1010

@@ -20,14 +20,15 @@ span.blocklyTreeLabel {
2020
font-weight: 200;
2121
}
2222

23-
.blocklyToolboxDiv, .monacoToolboxDiv {
24-
background-color: white !important;
25-
box-shadow: 4px 0px 2px -4px rgba(0,0,0,0.12), 4px 0px 2px -4px rgba(0,0,0,0.24);
23+
.blocklyToolbox, .monacoToolboxDiv {
24+
background-color: var(--pxt-target-background3) !important;
25+
color: var(--pxt-target-foreground3);
26+
box-shadow: 4px 0px 2px -4px var(--pxt-neutral-alpha10), 4px 0px 2px -4px var(--pxt-neutral-alpha20);
2627
}
2728

2829
/* Mobile */
2930
@media only screen and (max-width: @largestMobileScreen) {
30-
.blocklyToolboxDiv, .monacoToolboxDiv {
31+
.blocklyToolbox, .monacoToolboxDiv {
3132
border-left: 0 !important;
3233
}
3334
div.blocklyTreeRoot {
@@ -37,7 +38,7 @@ span.blocklyTreeLabel {
3738

3839
/* Tablet */
3940
@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
40-
.blocklyToolboxDiv, .monacoToolboxDiv {
41+
.blocklyToolbox, .monacoToolboxDiv {
4142
border-left: 0 !important;
4243
}
4344
div.blocklyTreeRoot {

theme/color-themes/microbit-dark.json

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
"id": "microbit-dark",
3+
"name": "Dark",
4+
"weight": 60,
5+
"monacoBaseTheme": "vs-dark",
6+
"overrideFiles": [
7+
"/overrides/microbit-dark-overrides.css"
8+
],
9+
"colors": {
10+
"pxt-header-background": "#181818",
11+
"pxt-header-foreground": "#ffffff",
12+
"pxt-header-background-hover": "#252525",
13+
"pxt-header-foreground-hover": "#ffffff",
14+
"pxt-header-stencil": "#323232",
15+
16+
"pxt-primary-background": "#0078D4",
17+
"pxt-primary-foreground": "#ffffff",
18+
"pxt-primary-background-hover": "#026EC1",
19+
"pxt-primary-foreground-hover": "#ffffff",
20+
"pxt-primary-accent": "#005ba1",
21+
22+
"pxt-secondary-background": "#63276d",
23+
"pxt-secondary-foreground": "#f3f2f1",
24+
"pxt-secondary-background-hover": "#742e80",
25+
"pxt-secondary-foreground-hover": "#f3f2f1",
26+
"pxt-secondary-accent": "#411a47",
27+
28+
"pxt-tertiary-background": "#0078d4",
29+
"pxt-tertiary-foreground": "#ffffff",
30+
"pxt-tertiary-background-hover": "#026EC1",
31+
"pxt-tertiary-foreground-hover": "#ffffff",
32+
"pxt-tertiary-accent": "#0894ff",
33+
34+
"pxt-target-background1": "#2d2d2d",
35+
"pxt-target-foreground1": "#f3f2f1",
36+
"pxt-target-background1-hover": "#202020",
37+
"pxt-target-foreground1-hover": "#ffffff",
38+
"pxt-target-stencil1": "#3b3a39",
39+
40+
"pxt-target-background2": "#181818",
41+
"pxt-target-foreground2": "#ffffff",
42+
"pxt-target-background2-hover": "#252525",
43+
"pxt-target-foreground2-hover": "#ffffff",
44+
"pxt-target-stencil2": "#323232",
45+
46+
"pxt-target-background3": "#1F1F1F",
47+
"pxt-target-foreground3": "#ffffff",
48+
"pxt-target-background3-hover": "#252525",
49+
"pxt-target-foreground3-hover": "#ffffff",
50+
"pxt-target-stencil3": "#323232",
51+
52+
"pxt-neutral-background1": "#1F1F1F",
53+
"pxt-neutral-foreground1": "#f3f2f1",
54+
"pxt-neutral-background1-hover": "#2c2c2c",
55+
"pxt-neutral-foreground1-hover": "#ffffff",
56+
"pxt-neutral-stencil1": "#3b3a39",
57+
58+
"pxt-neutral-background2": "#181818",
59+
"pxt-neutral-foreground2": "#ffffff",
60+
"pxt-neutral-background2-hover": "#252525",
61+
"pxt-neutral-foreground2-hover": "#ffffff",
62+
"pxt-neutral-stencil2": "#3b3a39",
63+
64+
"pxt-neutral-background3": "#202020",
65+
"pxt-neutral-foreground3": "#f3f2f1",
66+
"pxt-neutral-background3-hover": "#131313",
67+
"pxt-neutral-foreground3-hover": "#ffffff",
68+
"pxt-neutral-stencil3": "#070707",
69+
"pxt-neutral-background3-alpha90": "#202020e6",
70+
71+
"pxt-neutral-base": "rgba(180, 180, 180, 1)",
72+
"pxt-neutral-alpha0": "rgba(180, 180, 180, 0)",
73+
"pxt-neutral-alpha10": "rgba(180, 180, 180, 0.1)",
74+
"pxt-neutral-alpha20": "rgba(180, 180, 180, 0.2)",
75+
"pxt-neutral-alpha50": "rgba(180, 180, 180, 0.5)",
76+
"pxt-neutral-alpha80": "rgba(180, 180, 180, 0.8)",
77+
78+
"pxt-link": "#479ef5",
79+
"pxt-link-hover": "#62abf5",
80+
"pxt-focus-border": "#5caae5",
81+
82+
"pxt-colors-purple-background": "#63276d",
83+
"pxt-colors-purple-foreground": "#f3f2f1",
84+
"pxt-colors-purple-hover": "#742e80",
85+
"pxt-colors-purple-alpha10": "#63276d19",
86+
87+
"pxt-colors-orange-background": "#7a2101",
88+
"pxt-colors-orange-foreground": "#ffffff",
89+
"pxt-colors-orange-hover": "#932801",
90+
"pxt-colors-orange-alpha10": "#7a210119",
91+
92+
"pxt-colors-brown-background": "#50301a",
93+
"pxt-colors-brown-foreground": "#ffffff",
94+
"pxt-colors-brown-hover": "#633c20",
95+
"pxt-colors-brown-alpha10": "#50301a19",
96+
97+
"pxt-colors-blue-background": "#0078D4",
98+
"pxt-colors-blue-foreground": "#ffffff",
99+
"pxt-colors-blue-hover": "#026EC1",
100+
"pxt-colors-blue-alpha10": "#0078D419",
101+
102+
"pxt-colors-green-background": "#27ae60",
103+
"pxt-colors-green-foreground": "#ffffff",
104+
"pxt-colors-green-hover": "#1e8449",
105+
"pxt-colors-green-alpha10": "#27ae6019",
106+
107+
"pxt-colors-red-background": "#e74c3c",
108+
"pxt-colors-red-foreground": "#ffffff",
109+
"pxt-colors-red-hover": "#c0392b",
110+
"pxt-colors-red-alpha10": "#e74c3c19",
111+
112+
"pxt-colors-teal-background": "#1abc9c",
113+
"pxt-colors-teal-foreground": "#ffffff",
114+
"pxt-colors-teal-hover": "#16a085",
115+
"pxt-colors-teal-alpha10": "#1abc9c19",
116+
117+
"pxt-colors-yellow-background": "#fde300",
118+
"pxt-colors-yellow-foreground": "#000000",
119+
"pxt-colors-yellow-hover": "#e4cc00",
120+
"pxt-colors-yellow-alpha10": "#fde30019"
121+
}
122+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
#langmodal #availablelocales .langoption .header {
3+
/* Better contrast than default, which is purple */
4+
color: var(--pxt-neutral-foreground1);
5+
}
6+
7+
.pxtToolbox span.blocklyTreeLabel,
8+
.pxtToolbox .blocklyTreeSelected span.blocklyTreeLabel,
9+
.pxtToolbox .blocklyTreeSelected .blocklyTreeIcon {
10+
/* Better contrast in toolbox */
11+
color: var(--pxt-target-foreground3);
12+
}
13+
14+
.pxtToolbox #advanced > .blocklyTreeRow {
15+
/* Better contrast for advanced section color */
16+
border-color: var(--pxt-neutral-alpha80);
17+
}
18+
.pxtToolbox #advanced > .blocklyTreeRow .blocklyTreeIcon {
19+
/* Better contrast for advanced section arrow icon */
20+
color: var(--pxt-neutral-alpha80);
21+
}
22+
23+
.pxtToolbox #serial .blocklyTreeIcon,
24+
.tutorial-container .serial span.docs.inlineblock {
25+
/* Better contrast in toolbox & tutorial block colors, but try to preserve some of the icon color */
26+
filter: brightness(1.2) saturate(2);
27+
}
28+
29+
.pxtToolbox #control .blocklyTreeIcon,
30+
.tutorial-container .control span.docs.inlineblock {
31+
/* Better contrast in toolbox & tutorial block colors, but try to preserve some of the icon color */
32+
filter: brightness(1.2) saturate(2);
33+
}
34+
35+
#mainmenu {
36+
/* Some parts of the app use the same color as a background. This keeps the menu from blending in */
37+
border-bottom: 1px solid var(--pxt-header-stencil);
38+
}
39+
40+
.projectsdialog .ui.card:hover {
41+
/* Neutral and target colors are the same in dark theme, so it helps to have a clearer border when hovering over cards. */
42+
border-color: var(--pxt-focus-border) !important;
43+
}
44+
45+
#simulator #editorSidebar.editor-sidebar {
46+
/* Need a lighter background for sidebar to make the simulator stand out, since it's black on black otherwise */
47+
background-color: var(--pxt-target-background1);
48+
}
49+
50+
.fullscreensim #boardview {
51+
/* Gradient background is a little too intense in dark mode. Use a solid color instead */
52+
background: var(--pxt-target-background2);
53+
}
54+
55+
/*
56+
* Inverted image colors
57+
*/
58+
.barcharticon,
59+
.blockly-ws-search-next-btn,
60+
.blockly-ws-search-previous-btn,
61+
.blockly-ws-search-close-btn {
62+
filter: invert(1);
63+
}
64+
65+
.modals .ui.button.immersive-reader-button,
66+
#mainmenu .immersive-reader-button.ui.item,
67+
#simulator .editor-sidebar .immersive-reader-button.ui.item {
68+
background-image: url("/static/icons/immersive-reader-light.svg") !important;
69+
}
70+
71+
.carouselarrow {
72+
/* Better contrast, especially against images in carousels */
73+
opacity: 0.9;
74+
}
75+
76+
/* For inverted buttons, it almost always looks better to have the background be dark instead of light (even though non-inverted has a light foreground) */
77+
button.ui.button.inverted:not(.teaching-bubble-button),
78+
button.common-button.inverted:not(.teaching-bubble-button) {
79+
background-color: var(--pxt-neutral-background2) !important;
80+
}
81+
82+
button.ui.button.inverted:hover:not(.teaching-bubble-button),
83+
button.common-button.inverted:hover:not(.teaching-bubble-button) {
84+
background-color: var(--pxt-neutral-background2-hover) !important;
85+
}

theme/color-themes/overrides/microbit-light-overrides.css

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,47 @@
66
.theme-preview-microbit-light .theme-preview-sim-button {
77
background-color: var(--pxt-neutral-background2) !important;
88
}
9+
10+
#filelist, #editortools {
11+
/* Special textured backgrounds, but we only have assets for light theme */
12+
background: #fff url("/static/logo_texture.png") 0 0 repeat !important;
13+
}
14+
15+
/*
16+
* Adjustments to match the original micro:bit theme
17+
*/
18+
path.blocklyFlyoutBackground {
19+
fill: #4b4949 !important;
20+
}
21+
22+
.monacoFlyout {
23+
background: #4b4949 !important;
24+
}
25+
26+
#simulator .editor-sidebar .filemenu {
27+
background: var(--pxt-secondary-background);
28+
color: var(--pxt-secondary-foreground);
29+
}
30+
31+
#simulator .editor-sidebar .filemenu .item:hover, #simulator .editor-sidebar .filemenu .link.item:hover {
32+
background: var(--pxt-secondary-background-hover) !important;
33+
color: var(--pxt-secondary-foreground-hover) !important;
34+
}
35+
36+
#simulator .ui.button.play-button .icon.play {
37+
color: var(--pxt-colors-green-background) !important;
38+
}
39+
40+
.simtoolbar .ui.button.icon {
41+
background-color: #e0e1e2;
42+
color: rgba(0,0,0,.6);
43+
}
44+
45+
.simtoolbar .ui.button.icon:hover {
46+
filter: none;
47+
background-color: rgb(224, 225, 226);
48+
}
49+
50+
#serialPreview .label {
51+
border-color: var(--pxt-primary-background);
52+
}

theme/style.less

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,33 @@
2727
}
2828

2929
.ui.button.download-button {
30-
&:extend(.ui.purple.button all);
30+
background-color: var(--pxt-primary-background);
31+
color: var(--pxt-primary-foreground);
3132
}
3233

3334
.ui.button.hw-button {
34-
background-color: darken(@purple, 10%);
35+
background-color: var(--pxt-primary-accent) !important;
36+
color: var(--pxt-primary-foreground) !important;
3537
}
3638

3739
.docs.inlinebutton.ui.button.download-button:hover {
38-
&:extend(.ui.purple.button all);
40+
background-color: var(--pxt-primary-background);
41+
color: var(--pxt-primary-foreground);
3942
}
4043

41-
.ui.button.play-button.play-button-full {
42-
&:extend(.ui.inverted.button all);
43-
}
44-
45-
.ui.button.getting-started-btn {
46-
&:extend(.ui.orange.button all);
47-
}
48-
49-
.ui.button.editortools-btn {
50-
&:extend(.ui.blue.button all);
51-
}
44+
#editortools .ui.button.editortools-btn, .simtoolbar .ui.button.icon {
45+
background-color: var(--pxt-secondary-background);
46+
color: var(--pxt-secondary-foreground);
5247

53-
.ui.button.exit-tutorial-btn {
54-
&:extend(.ui.inverted.button all);
48+
&:hover {
49+
filter: none;
50+
background-color: var(--pxt-secondary-background-hover);
51+
color: var(--pxt-secondary-foreground-hover);
52+
}
5553
}
5654

57-
#filelist, #editortools {
58-
background: #fff data-uri("../docs/static/logo_texture.png") 0 0 repeat !important;
55+
#simulator .ui.button.play-button .icon.play {
56+
color: var(--pxt-secondary-foreground) !important;
5957
}
6058

6159
#downloadArea {
@@ -112,6 +110,10 @@
112110
}
113111
}
114112

113+
.sound-effect-header {
114+
background-color: rgb(230, 48, 34); // Match block color
115+
}
116+
115117
/* Mobile */
116118
@media only screen and (max-width: @largestMobileScreen) {
117119
#filelist {

0 commit comments

Comments
 (0)