mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-24 04:07:14 -05:00
522 lines
8.9 KiB
CSS
522 lines
8.9 KiB
CSS
.group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-2);
|
|
}
|
|
|
|
.matchCard {
|
|
container: match-card / inline-size;
|
|
position: relative;
|
|
overflow: hidden;
|
|
border-radius: var(--radius-box);
|
|
background-color: var(--color-bg-high);
|
|
|
|
/* only cards the scan just formed animate in — see MatchCard's `enter` */
|
|
&.enter {
|
|
animation: scanner-card-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
}
|
|
|
|
/* one overlay element all upload-state effects draw on */
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: inherit;
|
|
pointer-events: none;
|
|
}
|
|
|
|
&.flashUploaded::after {
|
|
animation: scanner-sent-pop 0.8s ease-out both;
|
|
}
|
|
}
|
|
|
|
@keyframes scanner-card-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(10px) scale(0.98);
|
|
}
|
|
}
|
|
|
|
@keyframes scanner-sent-pop {
|
|
0% {
|
|
opacity: 1;
|
|
box-shadow:
|
|
inset 0 0 0 2px var(--color-success),
|
|
inset 0 0 32px var(--color-success-low);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
box-shadow:
|
|
inset 0 0 0 2px var(--color-success),
|
|
inset 0 0 32px var(--color-success-low);
|
|
}
|
|
}
|
|
|
|
@keyframes scanner-shake {
|
|
20% {
|
|
transform: translateX(-4px);
|
|
}
|
|
50% {
|
|
transform: translateX(4px);
|
|
}
|
|
80% {
|
|
transform: translateX(-2px);
|
|
}
|
|
}
|
|
|
|
.head {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-2);
|
|
padding: var(--s-3) var(--s-4);
|
|
}
|
|
|
|
.matchCard.flashFailed .head {
|
|
animation: scanner-shake 0.35s ease;
|
|
}
|
|
|
|
.main {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--s-2) var(--s-3);
|
|
}
|
|
|
|
.numberColumn {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: var(--s-0-5);
|
|
}
|
|
|
|
.number {
|
|
font-size: 0.55rem;
|
|
font-weight: var(--weight-semi);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--color-text-high);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.scannedAt {
|
|
font-size: var(--font-2xs);
|
|
color: var(--color-text);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.mode {
|
|
flex-shrink: 0;
|
|
filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.5));
|
|
}
|
|
|
|
.headline {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-0-5);
|
|
/* claims row space so the score can never crush the stage name out of
|
|
view in a narrow column; wraps instead */
|
|
flex: 1 1 0;
|
|
min-width: 150px;
|
|
}
|
|
|
|
.title {
|
|
font-size: var(--font-sm);
|
|
line-height: 1.1;
|
|
}
|
|
|
|
.modeName {
|
|
font-weight: var(--weight-semi);
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.stage {
|
|
font-weight: var(--weight-extra);
|
|
}
|
|
|
|
.meta {
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-semi);
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.side {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--s-3);
|
|
margin-inline-start: auto;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.score {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--s-2);
|
|
font-weight: var(--weight-extra);
|
|
font-variant-numeric: tabular-nums;
|
|
line-height: 1;
|
|
padding: 5px var(--s-3);
|
|
border-radius: var(--radius-full);
|
|
background: color-mix(in oklab, var(--color-bg) 72%, transparent);
|
|
backdrop-filter: blur(8px);
|
|
}
|
|
|
|
.win {
|
|
color: var(--color-success-high);
|
|
font-size: var(--font-2xs);
|
|
letter-spacing: 0.08em;
|
|
}
|
|
|
|
.loss {
|
|
color: var(--color-error-high);
|
|
font-size: var(--font-2xs);
|
|
letter-spacing: 0.08em;
|
|
}
|
|
|
|
.scoreNumbers {
|
|
display: inline-flex;
|
|
gap: var(--s-1);
|
|
}
|
|
|
|
.scoreDash {
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.kds {
|
|
font-weight: var(--weight-bold);
|
|
font-variant-numeric: tabular-nums;
|
|
font-size: var(--font-xs);
|
|
padding: var(--s-0-5) var(--s-2);
|
|
border-radius: var(--radius-full);
|
|
background: color-mix(in oklab, var(--color-bg) 72%, transparent);
|
|
backdrop-filter: blur(8px);
|
|
}
|
|
|
|
.teamWeapons {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--s-1-5);
|
|
}
|
|
|
|
.weaponRow {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--s-1);
|
|
}
|
|
|
|
.vs {
|
|
margin: 0 var(--s-1);
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-semi);
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.weapon {
|
|
width: 28px;
|
|
height: 28px;
|
|
background: var(--color-bg-higher);
|
|
border-radius: var(--radius-full);
|
|
padding: 2px;
|
|
|
|
&.pov {
|
|
outline: 2px solid var(--color-fg-accent);
|
|
outline-offset: 1px;
|
|
}
|
|
}
|
|
|
|
.weaponUnknown {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-bold);
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.foot {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--s-2);
|
|
}
|
|
|
|
.footEnd {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--s-2);
|
|
margin-inline-start: auto;
|
|
}
|
|
|
|
.clips {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--s-1-5);
|
|
}
|
|
|
|
.clipChip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--s-1);
|
|
padding: var(--s-0-5) var(--s-2);
|
|
border: var(--border-style);
|
|
border-radius: var(--radius-full);
|
|
background: color-mix(in oklab, var(--color-bg) 72%, transparent);
|
|
backdrop-filter: blur(8px);
|
|
color: var(--color-text);
|
|
font: inherit;
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-bold);
|
|
font-variant-numeric: tabular-nums;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
color: var(--color-fg-accent);
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline: var(--focus-ring);
|
|
}
|
|
}
|
|
|
|
/* the shared circle button, translucent over the banner */
|
|
button.circle {
|
|
flex-shrink: 0;
|
|
width: 28px;
|
|
height: 28px;
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: var(--radius-full);
|
|
background: color-mix(in oklab, var(--color-bg) 55%, transparent);
|
|
backdrop-filter: blur(8px);
|
|
color: var(--color-text-high);
|
|
|
|
& svg {
|
|
width: var(--field-size-icon);
|
|
height: var(--field-size-icon);
|
|
}
|
|
|
|
&:hover {
|
|
color: var(--color-text);
|
|
background: color-mix(in oklab, var(--color-bg) 78%, transparent);
|
|
}
|
|
}
|
|
|
|
button.expand {
|
|
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
|
|
|
&.expanded {
|
|
transform: rotate(180deg);
|
|
}
|
|
}
|
|
|
|
/* the expanded content, indented under its card via a rail */
|
|
.details {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-4);
|
|
margin-inline-start: var(--s-2-5);
|
|
padding: var(--s-1) 0 var(--s-2) var(--s-3);
|
|
border-inline-start: var(--border-width) solid var(--color-border);
|
|
animation: scanner-detail-in 0.25s ease both;
|
|
}
|
|
|
|
@keyframes scanner-detail-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-4px);
|
|
}
|
|
}
|
|
|
|
.scoreboard {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
|
|
gap: var(--s-2);
|
|
}
|
|
|
|
.team {
|
|
padding: var(--s-2) var(--s-3);
|
|
border-radius: var(--radius-box);
|
|
background: color-mix(in oklab, var(--color-bg-high) 60%, transparent);
|
|
border: var(--border-width) solid var(--color-border);
|
|
|
|
&.teamWin {
|
|
border-color: var(--color-success-low);
|
|
}
|
|
|
|
&.teamLoss {
|
|
border-color: var(--color-error-low);
|
|
}
|
|
}
|
|
|
|
.teamHeading {
|
|
margin-bottom: var(--s-1-5);
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-semi);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.players {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: var(--font-xs);
|
|
|
|
& td {
|
|
padding: var(--s-1);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
& .weapon {
|
|
width: 36px;
|
|
height: 36px;
|
|
}
|
|
}
|
|
|
|
/* the round weapon badge plus the cell padding, so the image is never squeezed */
|
|
.weaponCell {
|
|
width: 48px;
|
|
}
|
|
|
|
.name {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 12rem;
|
|
}
|
|
|
|
.num {
|
|
text-align: right;
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.deathsKills {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
|
|
gap: var(--s-3);
|
|
}
|
|
|
|
.column {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-1);
|
|
}
|
|
|
|
.columnHeading {
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-semi);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--color-text-high);
|
|
}
|
|
|
|
.row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--s-2);
|
|
font-size: var(--font-xs);
|
|
}
|
|
|
|
.clock {
|
|
flex-shrink: 0;
|
|
width: 3rem;
|
|
color: var(--color-text-high);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.rowLabel {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.streak {
|
|
font-weight: var(--weight-bold);
|
|
color: var(--color-fg-accent);
|
|
}
|
|
|
|
.playSlot {
|
|
flex-shrink: 0;
|
|
width: 22px;
|
|
height: 22px;
|
|
}
|
|
|
|
.playButton {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
border: var(--border-style);
|
|
border-radius: var(--radius-full);
|
|
background: var(--color-bg);
|
|
color: var(--color-fg-accent);
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
background: var(--color-bg-higher);
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline: var(--focus-ring);
|
|
}
|
|
}
|
|
|
|
.builds {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-2);
|
|
}
|
|
|
|
.buildGrid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--s-3) var(--s-4);
|
|
}
|
|
|
|
.build {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--s-1);
|
|
}
|
|
|
|
.buildHead {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--s-1-5);
|
|
font-size: var(--font-2xs);
|
|
font-weight: var(--weight-semi);
|
|
}
|
|
|
|
.buildName {
|
|
max-width: 9rem;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.buildRows {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.buildRow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
min-height: 22px;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.matchCard,
|
|
.matchCard.flashUploaded::after,
|
|
.matchCard.flashFailed .head,
|
|
.details {
|
|
animation: none;
|
|
}
|
|
}
|