ui/playpage.razor.scss
@import "theme";
.play-page
{
font-family: $display-font;
color: $text-default;
position: relative;
width: 100%;
height: 100%;
}
.back-btn
{
flex-direction: row;
align-items: center;
gap: 10px;
padding: 14px 22px 14px 18px;
border-radius: 28px;
background-color: $surface-mid;
border: 2px solid rgba( 0, 0, 0, 0.1 );
cursor: pointer;
box-shadow: 0px 3px 0px $shadow-chunky;
transition: transform 0.12s ease-out;
&:hover { transform: translateY( -2px ); }
&:active { transform: translateY( 2px ); }
.back-glyph
{
width: 24px;
height: 24px;
}
.back-label
{
font-family: $display-font;
font-size: 14px;
font-weight: 800;
letter-spacing: 2px;
color: $text-default;
}
}
.settings-wrap
{
// Positioned so the pop-up panel anchors to the cog, not the card-stage.
// Sits above the countdown dim like the CTA.
position: relative;
z-index: 60;
}
.settings-btn
{
width: 52px;
height: 52px;
align-items: center;
justify-content: center;
border-radius: 28px;
background-color: $surface-mid;
border: 2px solid rgba( 0, 0, 0, 0.1 );
cursor: pointer;
box-shadow: 0px 3px 0px $shadow-chunky;
transition: transform 0.12s ease-out;
&:hover { transform: translateY( -2px ); }
&:active { transform: translateY( 2px ); }
.cog
{
font-size: 24px;
color: $text-default;
}
// Open flips dark, like the active mode tab.
&.open
{
background-color: $text-default;
border-color: $text-default;
.cog { color: white; }
}
}
.settings-panel
{
position: absolute;
top: 64px;
right: 0;
flex-direction: column;
gap: 24px;
padding: 18px 22px;
border-radius: $pill-radius;
background-color: white;
border: 2px solid rgba( 42, 31, 48, 0.1 );
box-shadow: 0px 3px 0px $shadow-chunky, 0px 6px 14px $shadow-soft;
z-index: 40;
transform: scale( 1 );
transition: transform 0.2s ease-out, opacity 0.2s ease-out;
width: 402px;
&:intro
{
transform: scale( 0.9 ) translateX( -128px );
opacity: 0;
}
}
.settings-row
{
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.settings-label
{
font-family: $display-font;
font-size: 12px;
font-weight: 800;
letter-spacing: 2px;
text-transform: uppercase;
color: $text-muted;
}
.stepper
{
flex-direction: row;
align-items: center;
gap: 8px;
}
.stepper-btn
{
width: 26px;
height: 26px;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: 800;
color: $text-default;
border-radius: 13px;
background-color: $surface-mid;
border: 2px solid rgba( 0, 0, 0, 0.1 );
cursor: pointer;
box-shadow: 0px 2px 0px $shadow-chunky;
transition: transform 0.12s ease-out;
&:hover { transform: translateY( -1px ); }
&:active { transform: translateY( 1px ); }
&.disabled
{
opacity: 0.4;
pointer-events: none;
box-shadow: none;
&:hover { transform: none; }
}
}
.stepper-value
{
width: 32px;
align-items: center;
justify-content: center;
font-family: $display-font;
font-size: 15px;
font-weight: 800;
color: $text-default;
}
.checkbox
{
width: 26px;
height: 26px;
align-items: center;
justify-content: center;
border-radius: 8px;
background-color: $surface-mid;
border: 2px solid rgba( 0, 0, 0, 0.1 );
cursor: pointer;
box-shadow: 0px 2px 0px $shadow-chunky;
transition: transform 0.12s ease-out;
&:hover { transform: translateY( -1px ); }
&:active { transform: translateY( 1px ); }
&.checked
{
background-color: $accent-green;
border-color: $accent-green;
}
.check-glyph
{
font-size: 15px;
font-weight: 800;
color: white;
}
}
.ready-status
{
font-family: $display-font;
font-size: 12px;
font-weight: 800;
letter-spacing: 3px;
color: $text-muted;
}
.mode-strip-wrap
{
position: absolute;
top: $deadzone-y;
left: $deadzone-x;
right: $deadzone-x;
flex-direction: row;
align-items: center;
justify-content: center;
transition: transform 0.35s ease-out, opacity 0.35s ease-out;
&:intro
{
transform: scale( 1.5 );
opacity: 0;
}
}
.mode-strip
{
flex-direction: row;
align-items: center;
gap: 8px;
}
.mode-tab
{
font-family: $display-font;
font-size: 12px;
font-weight: 800;
letter-spacing: 2px;
text-transform: uppercase;
padding: 10px 18px;
border-radius: 22px;
background-color: $surface-mid;
color: $text-muted;
border: 2px solid rgba( 42, 31, 48, 0.1 );
box-shadow: 0px 3px 0px $shadow-chunky;
}
// The active tab flips dark against the white pills.
.mode-tab.active
{
background-color: $text-default;
color: white;
border-color: $text-default;
box-shadow:
0px 3px 0px rgba( 0, 0, 0, 0.35 ),
0px 6px 14px $shadow-soft;
}
.mode-bumper
{
width: 28px;
height: 28px;
margin-left: 2px;
margin-right: 2px;
}
.card-stage
{
position: absolute;
top: 140px;
bottom: 160px;
left: $deadzone-x;
right: $deadzone-x;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 32px;
}
// READY UP is pinned to the true screen centre; BACK and the settings cog hang
// off it in absolute wings so appearing/disappearing never shifts the button.
.cta-row
{
width: 100%;
position: relative;
flex-direction: row;
align-items: center;
justify-content: center;
}
.cta-side
{
position: absolute;
flex-direction: row;
align-items: center;
}
.cta-left
{
right: 50%;
margin-right: 108px;
}
.cta-right
{
left: 50%;
margin-left: 108px;
}
.bottombar
{
position: absolute;
bottom: $deadzone-y;
left: $deadzone-x;
right: $deadzone-x;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 14px;
transition: transform 0.4s ease-out, opacity 0.4s ease-out;
&:intro
{
transform: scale( 1.5 );
opacity: 0;
}
}
.invite-hint
{
font-family: $display-font;
font-size: 14px;
font-weight: 900;
letter-spacing: 4px;
color: rgba( white, 0.8 );
}
// Clicking slots is a mouse affordance - hide the hint on controller.
.play-page.controller .invite-hint
{
display: none;
}
.primary-cta
{
flex-direction: row;
align-items: center;
gap: 10px;
padding: 14px 26px;
border-radius: 28px;
background-color: $accent-red;
cursor: pointer;
// Stay above the countdown dim (z 50) so you can still click to unready.
z-index: 60;
box-shadow: 0px 4px 0px rgba( 0, 0, 0, 0.18 );
transition: transform 0.12s ease-out;
&:hover { transform: translateY( -2px ); }
&:active { transform: translateY( 2px ); }
.cta-label
{
font-family: $header-font;
font-size: 18px;
font-weight: 800;
letter-spacing: 1px;
color: white;
text-transform: uppercase;
}
.cta-glyph
{
width: 24px;
height: 24px;
}
}
// Same button, recoloured once the local player has readied up - click to unready.
.primary-cta.is-ready
{
background-color: $accent-green;
}
.back-btn,
.mode-tab,
.primary-cta,
.settings-btn,
.stepper-btn,
.checkbox
{
pointer-events: none;
}
.play-page.mouse .back-btn,
.play-page.mouse .mode-tab,
.play-page.mouse .primary-cta,
.play-page.mouse .settings-btn,
.play-page.mouse .stepper-btn,
.play-page.mouse .checkbox
{
pointer-events: all;
cursor: pointer;
}
// Settings panel is a mouse affordance, like the invite hint.
.play-page.controller .settings-btn,
.play-page.controller .settings-panel
{
display: none;
}
// Disabled steppers stay inert even in mouse mode.
.play-page.mouse .stepper-btn.disabled
{
pointer-events: none;
cursor: default;
}
.play-page.mouse .mode-tab:hover
{
border-color: $accent-red;
sound-in: tab_switch;
}
.play-page.mouse .primary-cta:hover
{
transform: translateY( -2px );
sound-in: element_switch;
}
.countdown-overlay
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba( 42, 31, 48, 0.4 );
align-items: center;
justify-content: center;
z-index: 50;
// Don't intercept clicks - the unready CTA sits above this during the countdown.
pointer-events: none;
transition: opacity 0.2s ease-out;
&:intro
{
opacity: 0;
}
}