pxt-core
Version:
Microsoft MakeCode provides Blocks / JavaScript / Python tools and editors
1,212 lines (1,009 loc) • 27.8 kB
text/less
@defaultTutorialHeight: 18.625rem;
@tutorialFontSize: 1.125rem;
@tutorialTitleFontSize: 1.5rem;
@tutorialPrimaryColor: var(--pxt-colors-blue-background);
@tutorialSecondaryColor: var(--pxt-colors-blue-background);
@tutorialBarForegroundColor: @tutorialPrimaryColor;
@tutorialBarBackgroundColor: @tutorialSecondaryColor;
@tutorialLinkColor: var(--pxt-link);
@tutorialLinkHoverColor: var(--pxt-link-hover);
@tutorialHintForegroundColor: var(--pxt-colors-teal-background);
@tutorialHintBackgroundColor: var(--pxt-colors-teal-alpha10);
@tutorialTabletButtonColor: var(--pxt-neutral-background2);
@tutorialTabletSimulatorButtonColor: var(--pxt-neutral-alpha10);
@tutorialTabletStepCounterWidth: 16rem;
@tutorialHintMaskZIndex: -1; // Below tutorial pane
@tutorialControlsOffset: 5.725rem;
@tutorialBoardviewOffset: 3rem;
@tutorialTabBarOffset: 3.5rem;
@tutorialSimulatorMinHeight: 250px;
/*******************************
Tutorial Tab
*******************************/
#simulator .editor-sidebar .tutorial-container-outer.active {
background-color: var(--pxt-neutral-background1);
color: var(--pxt-neutral-foreground1);
}
.tutorial-container-outer {
background-color: var(--pxt-neutral-background1) ;
color: var(--pxt-neutral-foreground1);
}
.tutorial-content-bkg {
background-color: var(--pxt-neutral-background1);
color: var(--pxt-neutral-foreground1);
padding: 0.5rem 1rem;
}
.tutorial-container {
display: flex;
flex-direction: column;
height: 100%;
}
.tutorial-content {
flex: 1;
padding: 0;
margin-bottom: 0;
overflow-x: hidden;
overflow-y: auto;
font-family: @segoeUIFont;
font-size: @tutorialFontSize;
span.docs.inlineblock {
white-space: break-spaces;
}
p {
line-height: 1.6em;
}
hr {
border: 0;
border-top: 2px dashed @tutorialSecondaryColor;
}
.lang-block .ui.segment.raised, .lang-blocks .ui.segment.raised, .ui.segment.raised.codewidget {
overflow-x: auto;
background: var(--pxt-neutral-background2);
color: var(--pxt-neutral-foreground2);
code, code.hljs {
white-space: pre;
}
}
}
.tutorial-scroll-gradient {
position: absolute;
height: 3rem;
width: calc(~'100% - 1rem');
bottom: 0rem;
pointer-events: none;
background-image: linear-gradient(to bottom, var(--pxt-neutral-alpha0), var(--pxt-neutral-background1));
}
.tutorial-replace-code + .tutorial-scroll-gradient {
bottom: 2rem;
}
.tutorial-container,
.tutorial-controls {
.ui.button, .ui.button:hover {
box-shadow: none;
background-image: none;
}
}
.tutorial-controls {
border-top: 2px solid var(--pxt-neutral-alpha50);
margin-top: 1rem;
}
/*******************************
Exit Tutorial
*******************************/
.tutorial-exit {
position: absolute;
margin-right: 1rem;
top: 0;
right: 0;
color: @white;
font-size: @smallFontSize;
line-height: 3.5rem;
cursor: pointer;
}
.tutorial-exit:hover {
text-decoration: underline;
}
#mainmenu .tutorial-exit {
font-family: @segoeUIFont;
text-transform: uppercase;
}
/*******************************
Tutorial Top Buttons
*******************************/
.tutorial-top-bar {
display: flex;
align-items: flex-end;
padding: 0.5rem 1rem 0;
}
/*******************************
Header Bar
*******************************/
.tutorial-header-label {
display: flex;
flex-direction: row;
align-items: center;
.ui.item {
padding: 0.2rem ;
}
}
/*******************************
Step Counter
*******************************/
.tutorial-step-counter {
padding: 0.5rem 1rem;
border-bottom: 2px solid var(--pxt-neutral-stencil1);
background: var(--pxt-neutral-background1);
}
.tutorial-step-label {
display: flex;
user-select: none;
cursor: default;
font-size: 1rem;
color: var(--pxt-neutral-foreground1);
}
.tutorial-step-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tutorial-step-number:not(:first-child) {
flex-shrink: 0;
margin-left: 1rem;
}
#root.tabTutorial .tutorial-step-bubbles {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
margin-left: auto;
.circle-button {
transition: none;
width: 1rem;
height: 1rem;
// buttons before selected step
background: var(--pxt-colors-blue-background);
opacity: 0.6;
&.current {
opacity: 1;
color: var(--pxt-colors-blue-foreground);
background: var(--pxt-colors-blue-background);
width: 2rem;
height: 2rem;
user-select: none;
~ .circle-button {
// buttons after selected step
background: var(--pxt-neutral-alpha50);
opacity: 1;
}
}
&:focus-visible {
outline-offset: 2px;
outline: 4px solid var(--pxt-focus-border);
}
}
> .common-button.square-button {
border: solid 1px @tutorialPrimaryColor;
color: @tutorialPrimaryColor;
width: 2rem;
height: 2rem;
&.disabled {
visibility: hidden;
}
}
}
/*******************************
Title
*******************************/
.tutorial-title {
margin-bottom: 1rem;
font-size: @tutorialTitleFontSize;
font-weight: 700;
line-height: 1.2em;
}
/*******************************
Tutorial Controls
*******************************/
.tutorial-controls {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 1rem;
.ui.button {
margin: 0 1rem;
color: @white;
background: @tutorialPrimaryColor;
font-size: @tutorialFontSize;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
> .ui.button:last-child {
margin-left: auto;
}
.ui.button:hover, .ui.button:focus {
background: var(--pxt-colors-blue-hover);
color: var(--pxt-colors-blue-foreground);
}
.ui.button:focus-visible {
outline-offset: 2px;
outline: 4px solid var(--pxt-focus-border);
}
}
/*******************************
Tutorial Hint
*******************************/
.tutorial-hint.ui.button,
.tutorial-hint .ui.button {
height: 3rem;
width: 3rem;
margin: 0;
border-radius: 50%;
font-size: @tutorialTitleFontSize;
display: flex;
align-items: center;
justify-content: center;
> i {
display: flex;
align-items: center;
justify-content: center;
}
}
// Overrides, largely using old tutorial hint CSS
.tutorial-container-outer {
.tutorial-callout {
position: fixed;
top: unset;
right: unset;
bottom: 5rem;
left: 3rem;
max-width: 50%;
border-color: @tutorialHintBackgroundColor;
.hint-title {
margin-top: -.75rem;
> span {
font-weight: 700;
background-color: @tutorialHintBackgroundColor;
color: @tutorialHintForegroundColor;
padding: 0.25rem 0.75rem;
border-radius: 0.5rem;
}
}
}
.tutorial-callout:before {
display: none;
top: auto;
left: 6.5rem;
bottom: -2.5rem;
transform: rotate(-90deg);
}
.tutorial-callout-close.ui.button {
position: absolute;
right: 1rem;
padding: 0;
width: 1.5rem;
height: 1.5rem;
color: @white;
background-color: #000;
border-radius: 50%;
i.icon {
opacity: 1;
font-size: 1rem;
margin: 0 ;
}
}
}
.tutorial-callout-mask {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: @tutorialHintMaskZIndex;
}
/*******************************
Tutorial Markdown
*******************************/
.formatted-bullet-ul {
padding: 0;
}
.formatted-bullet-li {
display: flex;
position: relative;
p { padding: 0.4rem 0; }
}
.formatted-bullet {
margin-right: 0.5rem;
flex-shrink: 0;
background: linear-gradient(@tutorialPrimaryColor, @tutorialPrimaryColor) ~'no-repeat 45% / 2px 100%';
}
.formatted-bullet i.icon,
.formatted-bullet i.xicon {
display: block;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
color: @white;
background-color: @tutorialPrimaryColor;
line-height: 2.5rem;
text-align: center;
}
.formatted-bullet-ul .formatted-bullet-li:last-child {
min-height: 3.5rem;
}
.formatted-bullet-ul .formatted-bullet-li:last-child .formatted-bullet:after {
content: " ";
position: absolute;
width: 1rem;
bottom: 0;
left: 0.75rem;
border-bottom: 2px solid @tutorialPrimaryColor;
}
/*******************************
Tutorial Replace Code
*******************************/
.tutorial-replace-code {
display: flex;
justify-content: center;
font-family: @segoeUIFont;
.tutorial-callout-button.ui.button {
padding: 0;
margin: 0 0 1rem;
color: @tutorialLinkColor;
background: none transparent;
font-family: @segoeUIFont;
font-weight: 500;
}
.tutorial-callout-button.ui.button:hover,
.tutorial-callout-button.ui.button:focus {
color: @tutorialLinkHoverColor;
}
.tutorial-callout {
bottom: 5rem;
padding: 1rem;
max-width: 32rem;
}
.tutorial-replace-code-actions {
display: flex;
justify-content: flex-end;
}
}
/*******************************
Simulator Container
*******************************/
.simulator-container.hidden {
display: block ;
}
.simulator-container .simPanel {
height: 100%;
padding: 1rem 0.5rem 1rem 1rem;
overflow-x: hidden;
overflow-y: scroll;
&.ui.items { margin-top: 0; }
}
// Mini sim is visible when tab is hidden
#root.tabTutorial {
&:not(.fullscreensim) .simulator-container.hidden {
height: 0;
padding: 0;
.simPanel {
& > * { display: none; }
#boardview { display: inline-block; }
.simtoolbar, #miniSimOverlay { display: block; }
.play-button { display: none ; }
.expand-button, .fullscreen-button, .tutorial.mute-button { display: block ; }
display: flex;
align-items: flex-end;
aside.simtoolbar {
float: unset;
}
}
.tutorial-controls { display: none; }
/** TODO: change when supporting small horizontal sim && make not arcade centric at that time. **/
#boardview.ui.vertical.editorFloat, #boardview #simulators .simframe {
width: 17rem ;
}
#boardview #simulators {
justify-content: flex-end;
.simframe {
margin-right: @tutorialSimframeMargin;
}
}
aside.simtoolbar {
z-index: 5;
}
}
.simulator-container:not(.hidden) {
.simPanel {
height: calc(100% - @tutorialControlsOffset);
.button.hidefullscreen { display: none ; }
}
}
&.collapsedEditorTools:not(.fullscreensim) .simulator-container.hidden .simPanel{
.fullscreen-button, .tutorial.mute-button { display: none ; }
}
#miniSimOverlay {
display: none ;
}
}
/*******************************
Skillmap Embed View
*******************************/
.tabTutorial.tutorial-embed {
#simulator .editor-sidebar, #maineditor, &.sideDocs #sidedocs, .simView #simulators {
top: 0;
}
.simView #boardview {
padding-top: 0;
}
}
/*******************************
Headless (no simulator)
*******************************/
#root.headless.tabTutorial {
#simulator .editor-sidebar {
display: block;
position: absolute;
background: none transparent;
min-width: inherit;
max-width: inherit;
top: @mainMenuHeight;
bottom: 0;
left: 0;
&:not(.topInstructions) {
width: @simulatorWidth;
}
.simPanel {
display: none;
}
}
#boardview, .filemenu {
display: auto;
}
&:not(.tutorialSimSidebar) #maineditor {
left: @simulatorWidth;
}
}
#root.headless.tabTutorial.notificationBannerVisible #simulator .editor-sidebar {
top: calc(@mainMenuHeight + @bannerHeight);
}
#root.headless.tabTutorial.hideMenuBar {
#simulator .editor-sidebar {
top: 0;
height: 100%;
}
}
/*******************************
Keymap
*******************************/
.tabTutorial .keymap.above {
top: calc(5.5rem + @mainMenuHeight);
}
/*********************************
Accordion Hints (details)
*********************************/
.tabTutorial details {
padding: .5rem;
margin-bottom: 1rem;
color: @tutorialHintForegroundColor;
background-color: @tutorialHintBackgroundColor;
border-radius: .5rem;
summary {
cursor: pointer;
}
}
.tabTutorial {
.immersive-reader-button.ui.item {
float: right;
border: 2px solid var(--pxt-neutral-stencil1);
margin-left: 1.5rem;
}
}
/*********************************
Validation
*********************************/
.tutorial-validation-error-container {
position: fixed;
top: unset;
right: unset;
bottom: 5.5rem;
left: @simulatorWidth + 1rem;
max-width: 60%;
min-width: 18.75rem;
max-height: 70%;
background: var(--pxt-neutral-background1);
color: var(--pxt-neutral-foreground1);
box-shadow: 0 0rem 0.5rem;
border-radius: 0.5rem;
z-index: 40;
}
.tutorial-validation-error-body {
display: flex;
flex-direction: row;
padding: 2rem 2rem 2rem 0.5rem;
}
.tutorial-validation-error-hint {
padding: 1.5rem;
}
.tutorial-validation-error-inner {
display: flex;
flex-direction: column;
}
.tutorial-validation-error-emoji {
padding: 0.5rem 1rem 0 0.2rem;
width: 6rem;
}
.tutorial-validation-error-controls {
display: flex;
justify-content: right;
margin: 0;
margin-top: 0.5rem;
> .common-button {
width: unset;
}
}
.tutorial-validation-error-close.common-button {
position: absolute;
right: 0.6rem;
top: 0.8rem;
padding: 0 ;
i.right {
opacity: 1;
font-size: 1.3rem;
margin: 0 ;
}
}
.tutorial-validation-answer-key-hint {
max-height: 50vh;
overflow: auto;
padding-right: 2rem;
}
/* Remove border around blocks in the hint */
.tutorial-validation-answer-key-hint .lang-blocks .segment.raised {
border: none;
background: none;
box-shadow: none;
padding: 0;
}
/*************************************
Top-Instruction Layout
(tablet & sim-sidebar views)
*************************************/
.topInstructionsSettings() {
#root.tabTutorial,
#root.headless.tabTutorial {
#maineditor > .full-abs {
top: @defaultTutorialHeight;
}
#simulator .editor-sidebar {
display: block ;
height: @defaultTutorialHeight;
width: 100% ;
}
}
.tutorial-title {
margin-bottom: 0.2rem;
}
.tutorial-content-bkg {
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: .5rem 1rem 0.7rem 1rem;
.tutorial-step-content {
margin-right: 1.5rem;
}
.immersive-reader-button {
position: absolute;
top: 0.3rem;
right: 1rem;
}
}
.tutorial-step-label {
display: none;
}
.tutorial-callout-button.ui.button {
height: 2.5rem;
width: 2.5rem;
font-size: 1.1em;
}
.editor-sidebar {
border-right: 0;
border-bottom: 0;
}
.tutorial-container-outer {
padding-top: 0;
}
.tutorial-container {
flex-direction: row;
}
.tutorial-content {
margin: 0;
padding-bottom: 0;
}
.tutorial-replace-code + .tutorial-scroll-gradient,
.tutorial-scroll-gradient {
bottom: 0;
}
/*******************************
Exit Tutorial
*******************************/
.simulator-container.hidden .tutorial-exit {
// Shift in tutorial tab to make space for step counter
right: @tutorialTabletStepCounterWidth;
margin-right: 0;
}
/*******************************
Tutorial Top Buttons
*******************************/
.tutorial-top-bar {
position: absolute;
top: 0;
right: 0;
width: @tutorialTabletStepCounterWidth;
flex-direction: row-reverse;
padding: 0.5rem 1rem;
}
/*******************************
Step Counter
*******************************/
.tutorial-step-counter {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
padding: 0 0;
column-gap: 1rem;
border-bottom: unset;
margin-left: auto;
.ui.button {
margin: 0;
padding: 0.65rem;
.icon {
margin-left: 0;
}
}
.counter-previous-button .icon {
margin: 0;
}
}
.tutorial-step-bubbles {
min-width: 30rem;
}
.common-button.square-button {
margin: 0;
border: unset;
color: @white ;
background: @tutorialPrimaryColor;
}
/*******************************
Tutorial Hint
*******************************/
.tutorial-controls {
display: flex;
align-items: center;
margin: 0;
margin-top: 0.5rem;
padding: 0.7rem 0 0 0;
> .ui.button {
width: unset;
}
}
.tutorial-hint .tutorial-callout-button.ui.button.disabled {
display: none;
}
// Overrides
.tutorial-container-outer:not(.topInstructions) {
.tutorial-callout {
bottom: unset;
left: unset;
top: unset;
max-width: 80%;
transform: translateY(15px);
}
.tutorial-callout:before {
top: -2.5rem;
left: unset;
bottom: auto;
right: 3.5rem;
transform: rotate(90deg);
}
}
/*******************************
Tutorial Replace Code
*******************************/
.tutorial-replace-code {
position: absolute;
right: 4.5rem;
bottom: -0.5rem;
width: 4rem;
.tutorial-callout {
max-width: 32rem;
transform: translateY(65px);
}
.tutorial-replace-code-actions .ui.button {
width: unset;
}
}
.tutorial-replace-code ~ .tutorial-controls > .tutorial-hint {
width: 5rem;
}
/*******************************
Simulator Tab
*******************************/
#root.tabTutorial:not(.fullscreensim) .simulator-container:not(.hidden) {
.simPanel {
display: flex;
position: relative;
height: 100%;
margin: 0 4rem;
z-index: 30;
#simulators {
width: 34rem;
margin: auto;
}
.simframe {
padding-bottom: 39% ;
}
.simtoolbar {
flex-direction: column;
flex-grow: 0;
width: 6rem;
margin-left: 1rem;
}
.simtoolbar > .buttons {
flex-direction: column;
}
}
#boardview {
width: 100% ;
}
.tutorial-controls {
position: absolute;
top: @tutorialTabBarOffset;
width: 100%;
height: calc(100% - @tutorialTabBarOffset);
justify-content: space-between;
z-index: 10;
.ui.button {
height: 100%;
}
.ui.button:not(:hover) {
background-color: @tutorialTabletSimulatorButtonColor;
}
> .ui.button:last-child {
margin-top: 0.75rem;
margin-bottom: 0.75rem;
}
}
}
/*******************************
Headless (no simulator)
*******************************/
#root.headless.tabTutorial.collapsedEditorTools {
#maineditor { left: 0; }
#simulator .editor-sidebar { width: 100%; }
.tutorial-top-bar {
right: 4rem;
}
#simulator .editor-sidebar .immersive-reader-button.ui.item,
#simulator .editor-sidebar .immersive-reader-button.ui.item:focus{
background-image: @immersiveReaderIcon;
}
.tutorial-step-counter {
color: @black;
}
.tutorial-hint .tutorial-callout-button.ui.button {
flex-direction: row;
width: 12rem;
margin: 3.5rem 1rem 0;
}
.tutorial-controls {
align-items: flex-start;
.ui.button i.icon {
margin-bottom: 0;
}
}
}
.tutorial-title {
max-width: calc(100% - 10rem);
}
/*******************************
Validation
*******************************/
.tutorial-validation-error-container {
right: 1rem;
left: unset;
}
}
/*******************************
Media Adjustments
*******************************/
@media only screen and (min-width: @largestSmallMonitor) {
#root.tabTutorial:not(.fullscreensim, .greenscreen, .tutorialSimSidebar) {
#editortools {
width: calc(100% - @simulatorWidth);
left: unset;
right: 0;
}
}
}
@media only screen and (min-width: @largestTabletScreen) and (max-width: @largestSmallMonitor) {
#root.tabTutorial:not(.fullscreensim, .greenscreen, .tutorialSimSidebar) {
#editortools {
width: calc(100% - @simulatorWidthSmall);
left: unset;
right: 0;
}
}
}
/* Desktop Only */
@media only screen and (min-width: @largestTabletScreen) {
#root.tabTutorial:not(.fullscreensim, .greenscreen) {
#simulator .editor-sidebar:not(.topInstructions):not(.tutorial-sim) {
bottom: 0;
}
.cloudstatusarea .cloudtext {
display: none;
}
}
#simulator .editor-sidebar:not(.topInstructions) .tutorial-container .tutorial-step-counter {
.tutorial-step-label {
display: none;
}
}
#simulator .editor-sidebar:not(.topInstructions) .tutorial-step-label {
font-size: 1rem;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.tutorial-container-outer:not(.topInstructions) {
.tutorial-controls {
padding-top: 1rem;
}
}
/* Short Desktop Only */
@media (max-height: @tallEditorBreakpoint) {
#root.tabTutorial:not(.fullscreensim) {
.simulator-container:not(.hidden) {
.simPanel {
height: calc(100% - @tutorialControlsOffset);
min-height: @tutorialSimulatorMinHeight;
}
#boardview {
height: calc(100% - @tutorialBoardviewOffset);
min-height: @tutorialSimulatorMinHeight;
}
#simulators {
height: 100%;
min-height: @tutorialSimulatorMinHeight;
}
.simframe {
height: 100%;
min-height: @tutorialSimulatorMinHeight;
}
}
}
}
.topInstructionsWrapper {
.topInstructionsSettings();
.tutorial-step-bubbles {
justify-content: flex-end ;
gap: 1.5rem;
.circle-button {
margin: 0;
}
}
.tutorial-callout {
right: unset;
top: unset;
bottom: unset;
left: unset;
}
}
}
/* <= Small Monitor (Mobile + Tablet + Small Monitor) */
@media only screen and (max-width: @largestSmallMonitor) {
.tutorial-validation-error-container {
left: @simulatorWidthSmall + 1rem;
}
}
/* <= Tablet (Mobile + Tablet) */
@media only screen and (max-width: @largestTabletScreen) {
.topInstructionsSettings();
.tutorial-step-bubbles {
min-width: 25rem;
}
#simulator .editor-sidebar,
#root.headless.tabTutorial #simulator .editor-sidebar {
top: @mobileMenuHeight;
}
.tutorial-container > .ui.button i.icon {
margin-bottom: 0.5rem;
}
}
/* thin tablet header */
@media only screen and (min-width: @largestMobileScreen) and (max-height: @tallEditorBreakpoint) {
#root.tabTutorial,
#root.headless.tabTutorial {
#simulator .editor-sidebar {
top: @thinMenuHeight;
}
}
}
.tutorial-video-embed {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
> button {
display: block;
margin-top: .5rem;
border: solid 1px @tutorialPrimaryColor;
color: @tutorialPrimaryColor;
}
}
.tutorial-step-content video {
max-width: 100%;
}
/* Mobile */
@media only screen and (max-width: @largestMobileScreen) {
#root.tabTutorial:not(.fullscreensim) .simulator-container:not(.hidden) .simPanel {
#simulators {
width: 16rem;
}
.simframe {
padding-bottom: 83% ;
}
}
#root.headless.tabTutorial.collapsedEditorTools {
.tutorial-hint .tutorial-callout-button.ui.button {
margin: 0;
}
}
.tutorial-title {
max-width: 100%;
}
.tutorial-step-bubbles {
min-width: 20rem;
.ui.button {
padding: 0.5rem;
.right {
padding: 0;
margin: 0;
}
}
.counter-next-button .common-button-label {
display: none;
}
}
.tutorial-header-label .tutorial-header-step-label {
display: none ;
}
/*******************************
Validation
*******************************/
.tutorial-validation-error-container {
max-width: unset;
min-width: unset;
right: 2.5%;
width: 95%;
bottom: 1rem;
}
.tutorial-validation-error-body {
padding: 1.2rem 1rem 1rem 1rem;
}
.tutorial-validation-error-emoji {
display: none;
}
.tutorial-validation-error-controls {
justify-content: left;
> .common-button {
padding: .8rem 0.8rem 0.8rem 0.25rem;
}
}
.tutorial-validation-error-close.common-button {
right: 0.3rem;
}
}