From b952bc1e859960d6b502c951472777e02570546d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:45:30 +0000 Subject: [PATCH 1/4] Initial plan From 8515201e7bdc3557a7176f3eeb097bc9745dedd0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:48:48 +0000 Subject: [PATCH 2/4] Apply MakeCode loader brand color Co-authored-by: abchatra <6107272+abchatra@users.noreply.github.com> --- skillmap/src/styles/makecode-editor.css | 1 + 1 file changed, 1 insertion(+) diff --git a/skillmap/src/styles/makecode-editor.css b/skillmap/src/styles/makecode-editor.css index 8a7b9509061a..12ee3b82a3c5 100644 --- a/skillmap/src/styles/makecode-editor.css +++ b/skillmap/src/styles/makecode-editor.css @@ -31,6 +31,7 @@ .makecode-frame-loader img { max-width: 200px; vertical-align: middle; + filter: hue-rotate(290deg); -webkit-animation: loader-pxt 2s infinite linear; animation: loader-pxt 2s infinite linear; From bacb3428922cb435b917e9eaa216bac9eb3d81e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:52:31 +0000 Subject: [PATCH 3/4] Document loader color transformation Co-authored-by: abchatra <6107272+abchatra@users.noreply.github.com> --- skillmap/src/styles/makecode-editor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skillmap/src/styles/makecode-editor.css b/skillmap/src/styles/makecode-editor.css index 12ee3b82a3c5..cf6ad2fbfea3 100644 --- a/skillmap/src/styles/makecode-editor.css +++ b/skillmap/src/styles/makecode-editor.css @@ -31,7 +31,7 @@ .makecode-frame-loader img { max-width: 200px; vertical-align: middle; - filter: hue-rotate(290deg); + filter: hue-rotate(290deg); /* Convert target orange to MakeCode magenta */ -webkit-animation: loader-pxt 2s infinite linear; animation: loader-pxt 2s infinite linear; From c0b87734584472e08aae9eb2a46799bd2b06896d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 25 Aug 2026 22:35:14 +0000 Subject: [PATCH 4/4] Replace loader hue-rotate with themeable mask overlay Co-authored-by: abchatra <6107272+abchatra@users.noreply.github.com> --- skillmap/src/App.tsx | 5 ++- skillmap/src/components/LoaderLogo.tsx | 25 ++++++++++++ skillmap/src/components/makecodeFrame.tsx | 5 ++- skillmap/src/styles/makecode-editor.css | 47 ++++++++++++++++++++--- 4 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 skillmap/src/components/LoaderLogo.tsx diff --git a/skillmap/src/App.tsx b/skillmap/src/App.tsx index bf975ebb4c11..fa0bc5e048d6 100644 --- a/skillmap/src/App.tsx +++ b/skillmap/src/App.tsx @@ -37,12 +37,13 @@ import { InfoPanel } from './components/InfoPanel'; import { parseSkillMap } from './lib/skillMapParser'; import { parseHash, getMarkdownAsync, MarkdownSource, parseQuery, - setPageTitle, setPageSourceUrl, ParsedHash, resolvePath } from './lib/browserUtils'; + setPageTitle, setPageSourceUrl, ParsedHash } from './lib/browserUtils'; import { MakeCodeFrame } from './components/makecodeFrame'; import { getLocalUserStateAsync, getUserStateAsync, saveUserStateAsync } from './lib/workspaceProvider'; import { Unsubscribe } from 'redux'; import { UserProfile } from './components/UserProfile'; +import { LoaderLogo } from './components/LoaderLogo'; import { ReadyResources, ReadyPromise } from './lib/readyResources'; import { LanguageSelector } from '../../react-common/components/language/LanguageSelector'; import { ThemePickerModal } from '../../react-common/components/theming/ThemePickerModal'; @@ -452,7 +453,7 @@ class AppImpl extends React.Component { return (
{showingSyncLoader &&
- {lf("MakeCode +
{lf("Saving to cloud...")}
}
diff --git a/skillmap/src/components/LoaderLogo.tsx b/skillmap/src/components/LoaderLogo.tsx new file mode 100644 index 000000000000..b5634b396d1d --- /dev/null +++ b/skillmap/src/components/LoaderLogo.tsx @@ -0,0 +1,25 @@ +import * as React from "react"; +import { resolvePath } from "../lib/browserUtils"; + +interface LoaderLogoProps { + alt: string; +} + +/** + * Renders the animated loading logo. The logo image is painted as-is by + * default, but targets can recolor a single-color logo by setting the + * --pxt-loader-logo-color css variable, which paints the logo shape (used as + * a mask) in that color instead. + */ +export const LoaderLogo = (props: LoaderLogoProps) => { + const { alt } = props; + const logoUrl = resolvePath("assets/logo.svg"); + + return
+ {alt} +
+
+} diff --git a/skillmap/src/components/makecodeFrame.tsx b/skillmap/src/components/makecodeFrame.tsx index 0eda4efbc782..e2643fa62a27 100644 --- a/skillmap/src/components/makecodeFrame.tsx +++ b/skillmap/src/components/makecodeFrame.tsx @@ -1,7 +1,7 @@ /// import * as React from "react"; import { connect } from 'react-redux'; -import { isLocal, resolvePath, getEditorUrl, tickEvent, cloudLocalStoreKey } from "../lib/browserUtils"; +import { isLocal, getEditorUrl, tickEvent, cloudLocalStoreKey } from "../lib/browserUtils"; import { lookupActivityProgress } from "../lib/skillMapUtils"; import { SkillMapState } from '../store/reducer'; @@ -13,6 +13,7 @@ import '../styles/makecode-editor.css' import { ShareData } from "react-common/components/share/Share"; import { ProgressBar } from "react-common/components/controls/ProgressBar"; import { ThemeManager } from "react-common/components/theming/themeManager"; +import { LoaderLogo } from "./LoaderLogo"; interface MakeCodeFrameProps { save: boolean; mapId: string; @@ -130,7 +131,7 @@ class MakeCodeFrameImpl extends React.Component
- {imageAlt} + {openingProject && }
{loadingText}
diff --git a/skillmap/src/styles/makecode-editor.css b/skillmap/src/styles/makecode-editor.css index cf6ad2fbfea3..213ba3d26ab3 100644 --- a/skillmap/src/styles/makecode-editor.css +++ b/skillmap/src/styles/makecode-editor.css @@ -28,14 +28,44 @@ display: none; } -.makecode-frame-loader img { +.makecode-frame-loader-logo { + position: relative; + display: inline-block; max-width: 200px; vertical-align: middle; - filter: hue-rotate(290deg); /* Convert target orange to MakeCode magenta */ - -webkit-animation: loader-pxt 2s infinite linear; - animation: loader-pxt 2s infinite linear; - } + -webkit-animation: loader-pxt 2s infinite linear; + animation: loader-pxt 2s infinite linear; +} + +.makecode-frame-loader-logo img { + display: block; + max-width: 100%; +} + +/* + * Paints the logo shape in --pxt-loader-logo-color on top of the logo image, + * allowing targets with a single-color logo to recolor it. Targets that leave + * --pxt-loader-logo-color unset (e.g. those with a full color logo) get a + * transparent overlay and the image is shown unmodified. + */ +.makecode-frame-loader-logo-color { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: var(--pxt-loader-logo-color, transparent); + + -webkit-mask-image: var(--pxt-loader-logo-image); + mask-image: var(--pxt-loader-logo-image); + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: contain; + mask-size: contain; +} .makecode-frame-loader-bar { --progress-bar-filled-color: var(--pxt-primary-background); @@ -62,10 +92,17 @@ .high-contrast .makecode-frame-loader img { filter: grayscale(100%) brightness(60%) contrast(400%); +} + +.high-contrast .makecode-frame-loader-logo { animation: none; -webkit-animation: none; } +.high-contrast .makecode-frame-loader-logo-color { + display: none; +} + .high-contrast .makecode-frame-loader-fill { background-color: var(--high-contrast-text); }