ui/mapcard.razor.scss
@import "theme";
@import "avatar";
MapCard .map-tile
{
flex-direction: column;
background-color: $surface-deep;
border: 2px solid $surface-light;
border-radius: 24px;
padding: 10px;
position: relative;
box-shadow:
0px 8px 0px rgba( 0, 0, 0, 0.06 ),
0px 24px 48px $shadow-soft;
}
.map-tile.is-hero
{
width: 500px;
z-index: 10;
transform-origin: center center;
transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0px 22px 56px rgba( 0, 0, 0, 0.4 );
&:intro
{
transform: scale( 1.1 ) translateY( -32px );
}
}
// Once a map is picked (local player readied) the active card scales up.
.map-tile.is-hero.locked
{
transform: scale( 1.1 );
box-shadow:
0px 0px 28px rgba( 124, 217, 168, 0.55 ),
0px 22px 56px rgba( 0, 0, 0, 0.4 );
.color-bar
{
background-color: $accent-green;
}
}
// Side cards drop to smoked glass so the scene shows through; hero stays white.
.map-tile.is-side
{
width: 325px;
background-color: $pill-dark;
border-width: 0px;
box-shadow: 0px 18px 44px rgba( 0, 0, 0, 0.35 );
z-index: 1;
transition: transform 0.2s ease-out, background-color 0.2s ease-out;
&:intro
{
transform: scale( 1.05 );
}
}
.photo
{
width: 100%;
height: 300px;
border-radius: 16px;
position: relative;
align-items: center;
justify-content: center;
overflow: hidden;
background-color: $bg-cream;
}
.map-tile.is-side .photo
{
height: 200px;
background-color: rgba( 255, 255, 255, 0.08 );
}
.map-tile.is-side .photo-empty
{
color: rgba( 255, 255, 255, 0.45 );
}
.photo-img
{
width: 100%;
height: 100%;
border-radius: 16px;
background-size: cover;
background-position: center;
}
// Corner badge on the hero photo that opens the leaderboard page.
.leaderboard-btn
{
position: absolute;
top: 10px;
left: 10px;
width: 40px;
height: 40px;
border-radius: 12px;
background-color: rgba( 255, 255, 255, 0.1 );
align-items: center;
justify-content: center;
z-index: 99999;
pointer-events: all;
backdrop-filter: blur(35px);
cursor: pointer;
transition: background-color 0.15s ease;
i
{
font-size: 22px;
color: #fff;
}
&:hover
{
background-color: rgba( 0, 0, 0, 0.45 );
}
}
// The host's pick is ringed so everyone can see what will launch, on top of any other state.
.map-tile.host-pick
{
box-shadow:
0px 0px 0px 3px $accent-yellow,
0px 18px 44px rgba( 0, 0, 0, 0.35 );
}
.map-tile.is-hero.host-pick
{
box-shadow:
0px 0px 0px 3px $accent-yellow,
0px 22px 56px rgba( 0, 0, 0, 0.4 );
}
// Voter avatars (each player's "vote" is the map they're browsing), bottom-left of the photo.
.vote-avatars
{
position: absolute;
bottom: 10px;
left: 10px;
flex-direction: row;
align-items: center;
z-index: 9999;
.vote-avatar
{
@include avatar( 30px );
border: 2px solid $surface-deep;
box-shadow: 0px 2px 6px rgba( 0, 0, 0, 0.4 );
margin-right: -10px;
&.is-host
{
border-color: $accent-yellow;
}
}
}
.map-tile.is-side .vote-avatars .vote-avatar
{
@include avatar( 24px );
border-width: 2px;
}
// Vote tally chip on the hero card, alongside the capacity chip.
.chip-votes
{
color: $text-bright;
background-color: $pill-dark-solid;
}
// Track-layout badge on the card (the PNG road fill is translucent, so it sits
// on its own backdrop). Both states are top/right-anchored with explicit sizes
// so the expand animates - mixed anchoring (bottom vs top) can't be lerped.
.minimap-overlay
{
position: absolute;
top: 318px;
right: 10px;
width: 72px;
height: 72px;
padding: 4px;
border-radius: 12px;
background-color: rgba( 0, 0, 0, 0.1 );
align-items: center;
justify-content: center;
z-index: 99999;
pointer-events: all;
cursor: pointer;
transition: all 0.2s ease-in-out;
&:hover
{
background-color: rgba( 0, 0, 0, 0.25 );
}
// Expanded: cover the photo area, with the square map centred inside it.
&.expanded
{
top: 10px;
width: 476px;
height: 300px;
border-radius: 16px;
background-color: rgba( 255, 255, 255, 0.1 );
backdrop-filter: blur( 15px );
}
}
// Square at every size during the animation.
.minimap-img
{
height: 100%;
aspect-ratio: 1;
}
.photo-empty
{
position: absolute;
font-family: $display-font;
font-size: 20px;
font-weight: 800;
letter-spacing: 4px;
color: rgba( 42, 31, 48, 0.25 );
}
.caption
{
flex-direction: column;
padding: 12px 8px 6px 8px;
}
.map-tile.is-side .caption
{
padding: 8px 6px 4px 6px;
}
.title-row
{
flex-direction: row;
align-items: center;
gap: 10px;
.color-bar
{
width: 5px;
height: 22px;
border-radius: 3px;
flex-shrink: 0;
background-color: $accent-yellow;
}
}
.title
{
font-family: $header-font;
font-size: 22px;
font-weight: 800;
color: $text-default;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.map-tile.is-side .title
{
font-size: 15px;
color: $hud-text;
}
.map-tile.is-side .title-row .color-bar
{
height: 16px;
}
.description
{
font-family: $display-font;
font-size: 13px;
color: $text-muted;
margin: 4px 0px 10px 15px;
}
.meta-row
{
flex-direction: row;
gap: 6px;
margin-left: 15px;
margin-top: 8px;
}
.chip
{
padding: 5px 12px;
border-radius: 14px;
font-family: $display-font;
font-size: 10px;
font-weight: 800;
letter-spacing: 1.5px;
text-transform: uppercase;
color: $text-on-yellow;
background-color: $accent-yellow;
align-items: center;
justify-content: center;
}
.cycle
{
position: absolute;
top: 50%;
margin-top: -26px;
height: 52px;
border-radius: 26px;
background-color: $surface-deep;
border: 2px solid rgba( 0, 0, 0, 0.08 );
flex-direction: row;
align-items: center;
justify-content: center;
gap: 4px;
z-index: 99999;
padding: 0 12px;
box-shadow:
0px 4px 0px rgba( 0, 0, 0, 0.1 ),
0px 10px 20px $shadow-soft;
.chevron
{
font-family: $display-font;
font-size: 26px;
font-weight: 800;
color: $text-default;
padding-bottom: 4px;
}
InputHint
{
width: 24px;
height: 24px;
}
}
.cycle-left { left: -36px; }
.cycle-right { right: -36px; }
.map-tile.is-side
{
pointer-events: none;
}
.play-page.mouse .map-tile.is-side
{
pointer-events: all;
cursor: pointer;
}
.play-page.mouse .map-tile.is-side:hover
{
background-color: $pill-hover;
}