2026-07-18 11:13:12 +08:00

1705 lines
34 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

:root {
--gk-page-width: 375px;
--gk-purple-950: #09063e;
--gk-purple-900: #140e64;
--gk-purple-700: #4b0bb5;
--gk-purple-500: #6954ec;
--gk-gold: #ffd66a;
--gk-text: #ffffff;
--gk-muted: rgba(255, 255, 255, 0.72);
--gk-panel: rgba(83, 89, 226, 0.92);
--gk-shadow: 0 16px 38px rgba(6, 2, 54, 0.34);
}
* {
box-sizing: border-box;
}
html {
min-width: 320px;
min-height: 100%;
background: var(--gk-purple-950);
}
body {
min-width: 320px;
min-height: 100%;
margin: 0;
overflow-x: hidden;
background: var(--gk-purple-950);
color: var(--gk-text);
font-family: 'Baloo 2', 'SF Pro Display', 'Segoe UI', Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
}
button,
input {
font: inherit;
}
button {
color: inherit;
}
button:focus-visible {
outline: 3px solid rgba(255, 238, 139, 0.84);
outline-offset: 2px;
}
[hidden] {
display: none !important;
}
.game-king-app {
position: relative;
width: min(100%, var(--gk-page-width));
min-height: 100vh;
margin: 0 auto;
overflow: hidden;
background:
radial-gradient(
circle at 84% 14%,
rgba(87, 55, 246, 0.72),
transparent 26%
),
linear-gradient(90deg, var(--gk-purple-900), var(--gk-purple-700));
box-shadow: 0 0 60px rgba(0, 0, 0, 0.62);
}
.hero {
position: relative;
z-index: 2;
width: 100%;
height: 501px;
/* `hidden` is a scroll container: focusing the intentionally off-canvas
Rule/Award art can set scrollLeft=45 and shift the whole Hero. `clip`
preserves Figma's crop without allowing focus-driven scrolling. */
overflow: hidden;
overflow: clip;
background:
radial-gradient(
circle at 50% 18%,
rgba(113, 114, 255, 0.72),
transparent 25%
),
radial-gradient(
circle at 16% 54%,
rgba(242, 89, 255, 0.3),
transparent 26%
),
linear-gradient(180deg, #101064 0%, #2923a2 46%, #141069 100%);
}
.hero-art {
position: absolute;
z-index: 3;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.hero::before,
.hero::after {
position: absolute;
right: 0;
left: 0;
content: '';
pointer-events: none;
}
.hero::before,
.hero::after {
display: none;
}
.hero::before {
z-index: 0;
bottom: 0;
height: 188px;
background:
linear-gradient(
156deg,
transparent 28%,
rgba(22, 15, 105, 0.72) 29% 42%,
transparent 43%
)
0 30px / 94px 135px repeat-x,
linear-gradient(
204deg,
transparent 34%,
rgba(44, 33, 143, 0.82) 35% 53%,
transparent 54%
)
35px 0 / 116px 156px repeat-x,
linear-gradient(180deg, transparent, rgba(7, 7, 52, 0.92));
opacity: 0.88;
}
.hero::after {
z-index: 1;
bottom: -24px;
height: 132px;
background:
radial-gradient(ellipse at 8% 100%, #171052 0 34%, transparent 35%),
radial-gradient(ellipse at 28% 100%, #0d0b45 0 40%, transparent 41%),
radial-gradient(ellipse at 54% 100%, #19115a 0 42%, transparent 43%),
radial-gradient(ellipse at 78% 100%, #100b49 0 39%, transparent 40%),
radial-gradient(ellipse at 98% 100%, #181051 0 36%, transparent 37%);
}
.hero-scene {
position: absolute;
z-index: 1;
inset: 0;
pointer-events: none;
}
.hero-orbit {
position: absolute;
border: 2px solid rgba(191, 188, 255, 0.2);
border-radius: 50%;
transform: rotate(-18deg);
}
.hero-orbit-one {
top: 27px;
left: -70px;
width: 510px;
height: 284px;
}
.hero-orbit-two {
top: 103px;
left: 38px;
width: 302px;
height: 162px;
border-color: rgba(255, 214, 106, 0.18);
transform: rotate(14deg);
}
.hero-diamond {
position: absolute;
top: 171px;
left: 50%;
width: 232px;
height: 168px;
background: linear-gradient(
145deg,
rgba(119, 105, 255, 0.46),
rgba(29, 22, 126, 0.06)
);
clip-path: polygon(50% 0, 100% 42%, 78% 100%, 22% 100%, 0 42%);
filter: drop-shadow(0 18px 24px rgba(17, 6, 89, 0.38));
transform: translateX(-50%);
}
.hero-brand {
position: absolute;
z-index: 3;
top: 29px;
right: 22px;
left: 22px;
text-align: center;
text-shadow:
0 4px 0 #38208b,
0 8px 18px rgba(8, 3, 66, 0.64);
}
.hero-season {
display: inline-block;
padding: 2px 16px;
border: 1px solid rgba(255, 231, 145, 0.6);
border-radius: 999px;
background: rgba(41, 29, 142, 0.62);
color: #ffe78f;
font-size: 13px;
font-weight: 800;
letter-spacing: 0.12em;
line-height: 22px;
text-transform: uppercase;
}
.hero-brand h1 {
display: flex;
margin: 2px 0 0;
align-items: center;
justify-content: center;
gap: 9px;
color: #fff;
font-family: 'Playball', 'Times New Roman', serif;
font-size: 62px;
font-style: italic;
font-weight: 800;
letter-spacing: -0.055em;
line-height: 0.98;
}
.hero-brand h1 span:last-child {
color: #ffe36e;
}
.hero-brand p {
margin: 5px 0 0;
color: rgba(255, 255, 255, 0.82);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.hero-gamepad {
position: absolute;
z-index: 2;
top: 209px;
left: 50%;
width: 238px;
height: 137px;
border: 5px solid rgba(236, 231, 255, 0.88);
border-radius: 68px 68px 46px 46px;
background:
radial-gradient(
circle at 50% 18%,
rgba(255, 255, 255, 0.82),
transparent 22%
),
linear-gradient(160deg, #8d79ff, #3d31b6 55%, #291d84);
box-shadow:
inset 0 -13px 0 rgba(21, 13, 93, 0.34),
0 18px 32px rgba(10, 3, 76, 0.48);
transform: translateX(-50%) rotate(-3deg);
}
.gamepad-dpad,
.gamepad-dpad::before {
position: absolute;
width: 16px;
height: 54px;
border-radius: 5px;
background: #25215b;
content: '';
}
.gamepad-dpad {
top: 39px;
left: 48px;
}
.gamepad-dpad::before {
transform: rotate(90deg);
}
.gamepad-stick {
position: absolute;
bottom: 22px;
width: 28px;
height: 28px;
border: 5px solid #ddd8ff;
border-radius: 50%;
background: #332777;
box-shadow: 0 4px 0 rgba(17, 12, 69, 0.5);
}
.gamepad-stick-left {
left: 83px;
}
.gamepad-stick-right {
right: 80px;
}
.gamepad-buttons {
position: absolute;
top: 32px;
right: 43px;
width: 58px;
height: 58px;
}
.gamepad-buttons b {
position: absolute;
width: 17px;
height: 17px;
border: 3px solid rgba(255, 255, 255, 0.75);
border-radius: 50%;
background: #ff5dbe;
box-shadow: 0 3px 0 rgba(40, 15, 99, 0.55);
}
.gamepad-buttons b:nth-child(1) {
top: 0;
left: 21px;
}
.gamepad-buttons b:nth-child(2) {
top: 21px;
right: 0;
background: #63d6ff;
}
.gamepad-buttons b:nth-child(3) {
bottom: 0;
left: 21px;
background: #ffd760;
}
.gamepad-buttons b:nth-child(4) {
top: 21px;
left: 0;
background: #8cff8e;
}
.side-actions {
position: absolute;
z-index: 4;
top: 327px;
right: -45px;
display: grid;
gap: 5px;
}
.side-action {
position: relative;
width: 136px;
height: 43px;
padding: 0 48px 0 20px;
overflow: hidden;
border: 0;
background: url('./assets/layers/side-action-frame.png') right center / auto
43px no-repeat;
color: #fff;
font-size: 19px;
font-weight: 700;
line-height: 43px;
text-align: center;
text-transform: capitalize;
text-shadow: 0 2px 4px #3839a7;
cursor: pointer;
}
.side-action:active {
transform: translateX(3px);
}
.countdown {
position: absolute;
z-index: 4;
top: 433px;
left: 50%;
display: flex;
height: 63px;
align-items: center;
gap: 8px;
transform: translateX(-50%);
}
.countdown-cell {
position: relative;
display: flex;
width: 53px;
height: 63px;
align-items: center;
justify-content: center;
background: url('./assets/layers/countdown-cell.png') center / 53px 63px
no-repeat;
filter: drop-shadow(0 3px 5px rgba(18, 6, 105, 0.48));
}
.countdown-cell strong {
position: relative;
z-index: 1;
margin-top: 2px;
font-size: 23px;
font-weight: 800;
line-height: 1;
text-shadow: 0 2px 3px #3c4bcc;
}
.countdown-cell small {
margin-left: 1px;
font-size: 17px;
font-weight: 800;
}
.countdown > i {
width: 0;
margin: 0 -5px;
font-size: 23px;
font-style: normal;
font-weight: 800;
text-shadow: 0 2px 4px #342298;
}
.event-stage {
position: relative;
min-height: calc(100vh - 501px);
padding: 5px 10px calc(10px + env(safe-area-inset-bottom));
background:
radial-gradient(
circle at 12px 148px,
rgba(255, 255, 255, 0.72) 0 1px,
transparent 1.8px
),
radial-gradient(
circle at 82% 330px,
rgba(211, 188, 255, 0.7) 0 1px,
transparent 2px
),
linear-gradient(
180deg,
rgba(100, 30, 203, 0.4),
rgba(27, 11, 132, 0.12)
),
url('./assets/layers/stage-background.jpg') top center / 100% auto
repeat-y,
linear-gradient(90deg, var(--gk-purple-900), var(--gk-purple-700));
}
.primary-tabs {
position: relative;
z-index: 3;
display: grid;
width: 351px;
height: 34px;
margin: 0 auto 15px;
grid-template-columns: repeat(3, 1fr);
gap: 4px;
}
.primary-tab {
position: relative;
min-width: 0;
height: 34px;
padding: 0 3px;
border: 0;
background: url('./assets/layers/tab-idle.png') center / 112px 34px
no-repeat;
color: rgba(255, 255, 255, 0.82);
font-family: 'Playball', 'Times New Roman', serif;
font-size: 16px;
font-style: italic;
font-weight: 700;
line-height: 34px;
white-space: nowrap;
text-align: center;
text-shadow: 0 1px 2px #1d2c7f;
cursor: pointer;
}
.primary-tab.is-active {
background-image: url('./assets/layers/tab-active.png');
color: #fff4fe;
font-size: 19px;
}
.view-panel {
position: relative;
min-height: 540px;
}
.section-state {
display: flex;
min-height: 360px;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
color: var(--gk-muted);
text-align: center;
}
.section-state p {
max-width: 260px;
margin: 0;
font-size: 15px;
line-height: 1.5;
}
.loading-spinner {
width: 32px;
height: 32px;
border: 3px solid rgba(255, 255, 255, 0.22);
border-top-color: var(--gk-gold);
border-radius: 50%;
animation: spinner 0.8s linear infinite;
}
@keyframes spinner {
to {
transform: rotate(1turn);
}
}
.retry-button {
min-width: 104px;
min-height: 40px;
padding: 8px 18px;
border: 1px solid rgba(255, 230, 124, 0.72);
border-radius: 20px;
background: rgba(67, 48, 178, 0.76);
box-shadow: var(--hy-theme-button-shadow);
color: #fff;
font-weight: 700;
cursor: pointer;
}
.lottery-content {
display: flex;
/* The wheel starts at y=555 in Figma. Only the draw control overlaps the
wheel base; moving this whole group would pull all seven prize cells up. */
margin-top: 0;
flex-direction: column;
align-items: center;
}
.wheel {
position: relative;
width: 355px;
height: 417px;
margin: 0 auto;
}
.wheel-frame {
position: absolute;
inset: 0;
width: 355px;
height: 417px;
object-fit: contain;
transform-origin: 50% 44%;
pointer-events: none;
filter: drop-shadow(0 12px 14px rgba(25, 4, 101, 0.42));
}
.wheel.is-spinning .wheel-frame {
animation: wheel-spin 1.55s cubic-bezier(0.12, 0.66, 0.16, 1) both;
}
@keyframes wheel-spin {
from {
transform: rotate(0);
}
to {
transform: rotate(1080deg);
}
}
.wheel-prizes {
position: absolute;
inset: 0;
z-index: 2;
margin: 0;
padding: 0;
list-style: none;
pointer-events: none;
}
.wheel-prize {
position: absolute;
width: 68px;
min-height: 71px;
transform: translate(-50%, -50%);
color: #ba3320;
text-align: center;
transition:
filter 0.2s ease,
transform 0.2s ease;
}
.wheel-prize:nth-child(1) {
top: 20%;
left: 50%;
}
.wheel-prize:nth-child(2) {
top: 29%;
left: 73%;
}
.wheel-prize:nth-child(3) {
top: 49%;
left: 80%;
}
.wheel-prize:nth-child(4) {
top: 68%;
left: 64%;
}
.wheel-prize:nth-child(5) {
top: 68%;
left: 40%;
}
.wheel-prize:nth-child(6) {
top: 49%;
left: 20%;
}
.wheel-prize:nth-child(7) {
top: 29%;
left: 27%;
}
.wheel-prize img {
display: block;
width: 50px;
height: 50px;
margin: 0 auto -1px;
border-radius: 10px;
object-fit: cover;
}
/* API media is optional while an operator is still configuring rewards. Keep the
* empty slot visually intentional; mock artwork is only used by ?mock=1. */
.media-placeholder {
display: block;
width: 50px;
height: 50px;
margin: 0 auto -1px;
border: 1px dashed rgba(180, 51, 32, 0.45);
border-radius: 10px;
background: radial-gradient(
circle,
rgba(255, 255, 255, 0.78),
rgba(255, 207, 92, 0.22)
);
}
.wheel-prize span {
display: block;
overflow: hidden;
font-size: 10px;
font-weight: 700;
line-height: 16px;
text-overflow: ellipsis;
white-space: nowrap;
}
.wheel-prize.is-winning {
z-index: 5;
filter: drop-shadow(0 0 11px #fffbd1) brightness(1.16);
transform: translate(-50%, -50%) scale(1.14);
}
.spin-button {
position: absolute;
z-index: 4;
top: 44%;
left: 50%;
width: 102px;
height: 112px;
padding: 0;
transform: translate(-50%, -50%);
border: 0;
background: transparent;
color: #ba3320;
cursor: pointer;
}
.spin-button img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.spin-button strong {
position: absolute;
top: 47px;
right: 0;
left: 0;
font-size: 21px;
line-height: 1;
}
.spin-button small {
position: absolute;
top: 76px;
left: 50%;
min-width: 36px;
height: 23px;
padding: 0 7px;
transform: translateX(-50%);
border: 1px solid #fb7185;
border-radius: 12px;
background: #e11d48;
color: #fff;
font-size: 12px;
font-weight: 800;
line-height: 21px;
}
.spin-button:disabled {
cursor: not-allowed;
filter: grayscale(0.45) brightness(0.82);
}
.lottery-progress {
/* The wheel centre already exposes the current draw count. Keeping this
live region in the DOM preserves the state/update contract without
adding the non-Figma progress card between the wheel and draw button. */
display: none;
width: 335px;
margin: -20px auto 10px;
padding: 11px 13px 10px;
border: 1px solid rgba(244, 227, 255, 0.32);
border-radius: 14px;
background: rgba(35, 20, 130, 0.7);
box-shadow: inset 0 1px rgba(255, 255, 255, 0.14);
font-size: 13px;
}
.lottery-progress > div:first-child {
display: flex;
align-items: center;
justify-content: space-between;
}
.lottery-progress strong {
color: #fff5b2;
font-size: 19px;
}
.records-link {
display: block;
margin: -21px 48px 4px auto;
padding: 0;
border: 0;
background: transparent;
color: #d9ddff;
font-size: 12px;
text-decoration: underline;
cursor: pointer;
}
.progress-track {
height: 7px;
overflow: hidden;
border-radius: 999px;
background: rgba(4, 3, 75, 0.56);
}
.progress-track span {
display: block;
width: 0;
height: 100%;
border-radius: inherit;
background: linear-gradient(90deg, #f7cc58, #fff5ac);
transition: width 0.3s ease;
}
.lottery-progress p {
margin: 5px 0 0;
color: #dfe1ff;
font-size: 11px;
line-height: 1.35;
text-align: center;
}
.draw-button {
position: relative;
width: 269px;
height: 48px;
/* Figma places the control at y=938 while the 417px wheel that starts at
y=555 ends at y=972, so the button intentionally overlaps by 34px. */
margin-top: -34px;
padding: 0 25px;
border: 0;
background: url('./assets/layers/draw-button.png') center / 269px 48px
no-repeat;
color: #501b00;
font-size: 15px;
font-weight: 800;
text-transform: capitalize;
cursor: pointer;
filter: drop-shadow(0 6px 7px rgba(27, 2, 75, 0.34));
}
.draw-button:disabled {
cursor: not-allowed;
filter: grayscale(0.7) brightness(0.68);
}
.rule-card {
width: 351px;
min-height: 172px;
margin: 15px auto 0;
padding: 11px 12px;
border-radius: 12px;
background:
linear-gradient(108deg, rgba(255, 255, 255, 0.13), transparent 45%),
var(--gk-panel);
box-shadow: var(--gk-shadow);
}
.rule-card h2 {
margin: 0 0 3px;
font-size: 24px;
line-height: 1.35;
}
.rule-card ol,
.rule-modal ol {
margin: 0;
padding-inline-start: 20px;
}
.rule-card li {
margin: 3px 0;
font-size: 15px;
font-weight: 700;
line-height: 1.45;
}
.ranking-panel {
min-height: 1180px;
/* The decorative self row reaches the 1827px frame edge; cancel only the
residual stage inset because the sticky row already honors safe area. */
margin-bottom: calc(-7px - env(safe-area-inset-bottom));
}
.period-tabs {
position: relative;
display: grid;
width: 351px;
height: 87px;
margin: -6px auto 8px;
padding: 21px 22px 19px;
grid-template-columns: 1fr 1fr;
background: url('./assets/layers/rank-period-frame.png') center / 351px 87px
no-repeat;
}
.period-tab {
position: relative;
z-index: 1;
min-width: 0;
border: 0;
background: transparent;
color: #fff;
font-size: 16px;
font-weight: 800;
white-space: nowrap;
cursor: pointer;
}
.period-tab::before {
position: absolute;
z-index: -1;
top: 50%;
left: 50%;
width: 157px;
height: 47px;
content: '';
opacity: 0;
transform: translate(-50%, -50%);
background: url('./assets/layers/rank-period-active.png') center / 157px
47px no-repeat;
transition: opacity 0.15s ease;
}
.period-tab.is-active {
color: #fff4a6;
}
.period-tab.is-active::before {
opacity: 1;
}
.rank-state {
min-height: 420px;
}
.rank-empty,
.reward-empty,
.records-empty {
padding: 64px 20px;
color: var(--gk-muted);
text-align: center;
}
.rank-empty span {
color: var(--gk-gold);
font-size: 42px;
}
.rank-podium {
position: relative;
width: 351px;
height: 328px;
/* Figma: podium group y=647, first standard row y=987. */
margin: 3px auto 12px;
padding: 0;
list-style: none;
}
.podium-user {
position: absolute;
width: 116px;
color: #fff;
text-align: center;
}
.podium-user[data-rank='1'] {
top: 0;
left: 50%;
width: 274px;
transform: translateX(-50%);
}
.podium-user[data-rank='2'] {
top: 145px;
left: 0;
width: 117px;
}
.podium-user[data-rank='3'] {
top: 145px;
right: 0;
width: 117px;
}
.podium-ring {
position: relative;
width: 117px;
height: 182px;
margin: 0 auto;
background: url('./assets/layers/rank-top2-frame.png') center / contain
no-repeat;
}
.podium-user[data-rank='1'] .podium-ring {
width: 274px;
height: 234px;
background-image: url('./assets/layers/rank-top1-frame.png');
}
.podium-user[data-rank='3'] .podium-ring {
background-image: url('./assets/layers/rank-top3-frame.png');
}
.podium-ring::before {
display: none;
}
.podium-user[data-rank='2'] .podium-ring::before {
filter: hue-rotate(26deg) saturate(0.74)
drop-shadow(0 5px 8px rgba(24, 4, 106, 0.4));
}
.podium-user[data-rank='3'] .podium-ring::before {
filter: hue-rotate(314deg) saturate(1.2)
drop-shadow(0 5px 8px rgba(24, 4, 106, 0.4));
}
.podium-avatar {
position: absolute;
z-index: 1;
top: 20%;
left: 25%;
width: 50%;
height: 32%;
overflow: hidden;
border: 2px solid rgba(255, 246, 181, 0.92);
border-radius: 50%;
background: linear-gradient(145deg, #4a70ff, #e36fe8);
object-fit: cover;
}
.avatar-fallback {
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(145deg, #506bff, #d866df);
color: #fff8bd;
font-size: 22px;
font-weight: 900;
text-shadow: 0 2px 3px rgba(26, 8, 99, 0.55);
}
.podium-avatar.avatar-fallback {
position: absolute;
}
.rank-avatar.avatar-fallback {
border: 2px solid #ffe86d;
}
.podium-rank {
display: none;
position: absolute;
right: 50%;
bottom: 7px;
min-width: 54px;
height: 25px;
padding: 0 8px;
transform: translateX(50%);
border-radius: 13px;
background: linear-gradient(180deg, #fff7be, #f4b516);
box-shadow: 0 2px 4px rgba(92, 42, 0, 0.34);
color: #8e4d00;
font-size: 14px;
font-weight: 900;
line-height: 25px;
}
.podium-name {
position: absolute;
z-index: 2;
top: 112px;
right: 13px;
bottom: auto;
left: 15px;
display: block;
max-width: none;
margin: 0;
overflow: hidden;
font-size: 12px;
font-weight: 800;
line-height: 17px;
text-overflow: ellipsis;
white-space: nowrap;
}
.podium-score {
position: absolute;
z-index: 2;
top: 130px;
right: 32px;
bottom: auto;
left: 32px;
display: block;
max-width: none;
margin: 0;
padding: 2px 4px;
overflow: hidden;
border: 1px solid #ffdf36;
border-radius: 11px;
background: rgba(238, 53, 126, 0.82);
font-size: 8px;
font-weight: 800;
line-height: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.podium-user[data-rank='1'] .podium-avatar {
top: 15%;
left: 30%;
width: 40%;
height: 47%;
}
.podium-user[data-rank='1'] .podium-name {
top: 152px;
right: auto;
bottom: auto;
left: 92px;
width: 89px;
font-size: 16px;
line-height: 22px;
}
.podium-user[data-rank='1'] .podium-score {
top: 178px;
right: auto;
bottom: auto;
left: 96px;
width: 82px;
font-size: 12px;
line-height: 18px;
}
.rank-list {
display: grid;
width: 375px;
margin: 0 -10px;
padding: 0;
/* Each 84px row advances by 96px in the source frame. */
gap: 12px;
list-style: none;
}
.rank-row,
.my-rank {
position: relative;
display: grid;
width: 375px;
height: 84px;
align-items: center;
padding: 10px 25px 10px 20px;
grid-template-columns: 32px 54px minmax(0, 1fr) auto;
gap: 8px;
background: url('./assets/layers/rank-row.png') center / 375px 84px
no-repeat;
}
.rank-number {
color: #fff6a6;
font-size: 17px;
font-weight: 900;
text-align: center;
text-shadow: 0 2px 3px #221295;
}
.rank-avatar {
width: 54px;
height: 54px;
border: 2px solid #ffe86d;
border-radius: 50%;
background: linear-gradient(145deg, #4353d8, #ca63dc);
object-fit: cover;
}
.rank-user-copy {
min-width: 0;
}
.rank-user-copy strong,
.rank-user-copy small {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rank-user-copy strong {
font-size: 13px;
}
.rank-user-copy small {
margin-top: 4px;
color: #d9d8ff;
font-size: 10px;
}
.rank-score {
max-width: 88px;
overflow: hidden;
color: #fff;
font-size: 13px;
font-weight: 800;
text-overflow: ellipsis;
white-space: nowrap;
}
.my-rank {
position: sticky;
z-index: 8;
bottom: env(safe-area-inset-bottom);
margin: 0 -10px;
background-image: url('./assets/layers/rank-self-row.png');
box-shadow: 0 -8px 22px rgba(20, 7, 95, 0.32);
}
.rewards-panel {
/* Frame 918:5732 ends at 2508px (501px Hero + 2007px stage). */
min-height: 1992px;
padding-top: 0;
}
/* Awards is entered from the Hero action rather than a primary section. The
* Figma view starts directly below the countdown with Back plus reward cards. */
.game-king-app.is-rewards-view .primary-tabs,
.game-king-app.is-rewards-view .rewards-heading {
display: none;
}
.game-king-app.is-rewards-view .rewards-panel {
padding-top: 3px;
}
.rewards-back {
position: absolute;
z-index: 3;
top: -47px;
right: 16px;
width: 37px;
height: 37px;
border: 3px solid #ffe767;
border-radius: 50%;
background: #4d2bc1;
box-shadow: 0 3px 7px rgba(15, 4, 75, 0.45);
color: #fff88a;
font-size: 22px;
font-weight: 900;
line-height: 29px;
cursor: pointer;
}
.rewards-heading {
display: flex;
width: 351px;
min-height: 42px;
align-items: center;
justify-content: center;
gap: 8px;
margin: -2px auto 8px;
border: 1px solid rgba(255, 227, 111, 0.6);
border-radius: 21px;
background: rgba(48, 28, 156, 0.76);
font-size: 18px;
font-weight: 800;
}
.rewards-heading small {
color: #fff0a0;
font-size: 11px;
}
.reward-tier-list {
display: grid;
/* First 351×317 card starts at y=516 in the Figma frame. */
padding-top: 7px;
gap: 12px;
}
.reward-tier {
position: relative;
width: 351px;
height: 317px;
margin: 0 auto;
overflow: hidden;
filter: drop-shadow(0 10px 13px rgba(22, 6, 93, 0.35));
}
/* The source art is a shared Figma image-fill whose top/middle/bottom slices
* make one card. Clipping the slices avoids treating the entire reward card as
* a fixed screen image while retaining the design's decorative geometry. */
.reward-panel-layer {
position: absolute;
z-index: 0;
inset: 0;
display: grid;
grid-template-rows: 92px 1fr 67px;
pointer-events: none;
}
.reward-panel-slice {
display: block;
background-image: url('./assets/layers/reward-panel.png');
background-repeat: no-repeat;
background-size: 351px 317px;
}
.reward-panel-slice.is-top {
background-position: center top;
}
.reward-panel-slice.is-middle {
background-position: center -92px;
}
.reward-panel-slice.is-bottom {
background-position: center bottom;
}
.reward-tier h3 {
position: absolute;
z-index: 1;
top: 16px;
right: 42px;
left: 42px;
margin: 0;
overflow: hidden;
font-family: 'Playball', Georgia, serif;
font-size: 30px;
font-style: italic;
font-weight: 700;
line-height: 45px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: 0 2px 4px #20299f;
}
.tier-rewards {
position: absolute;
z-index: 1;
top: 79px;
right: 13px;
left: 13px;
display: flex;
gap: 8px;
overflow-x: auto;
overscroll-behavior-inline: contain;
scrollbar-width: none;
}
.tier-rewards::-webkit-scrollbar {
display: none;
}
.tier-reward {
width: 100px;
min-width: 100px;
text-align: center;
}
.tier-reward-media {
position: relative;
width: 100px;
height: 99px;
margin: 0 auto;
background: url('./assets/layers/reward-ring.png') center / 100px 99px
no-repeat;
}
.tier-reward-media img {
position: absolute;
top: 19px;
left: 19px;
width: 62px;
height: 62px;
border-radius: 11px;
object-fit: cover;
}
.tier-reward-media .media-placeholder {
position: absolute;
top: 19px;
left: 19px;
width: 62px;
height: 62px;
margin: 0;
}
.tier-reward-count {
width: 100px;
height: 17px;
margin-top: 3px;
background: url('./assets/layers/reward-count-frame.png') center / 100px
17px no-repeat;
color: #fff;
font-size: 11px;
font-weight: 800;
line-height: 17px;
text-align: center;
}
.tier-reward-name {
display: none;
margin-top: 2px;
overflow: hidden;
color: #32318f;
font-size: 9px;
font-weight: 800;
text-overflow: ellipsis;
white-space: nowrap;
}
.reward-status {
position: absolute;
z-index: 1;
bottom: 34px;
left: 50%;
width: 200px;
height: 53px;
padding: 0 17px;
transform: translateX(-50%);
background: url('./assets/layers/reward-status-frame.png') center / 200px
53px no-repeat;
color: #fff;
font-family: 'Playball', Georgia, serif;
overflow: hidden;
font-size: 14px;
font-style: italic;
font-weight: 700;
line-height: 53px;
text-align: center;
text-shadow: 0 2px 3px #a65b00;
text-overflow: ellipsis;
white-space: nowrap;
}
.toast {
position: fixed;
z-index: 80;
bottom: calc(28px + env(safe-area-inset-bottom));
left: 50%;
width: min(320px, calc(100vw - 32px));
padding: 11px 16px;
transform: translateX(-50%);
border: 1px solid rgba(255, 229, 116, 0.42);
border-radius: 14px;
background: rgba(20, 10, 92, 0.94);
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.38);
color: #fff;
font-size: 13px;
font-weight: 700;
line-height: 1.4;
text-align: center;
}
.modal-backdrop {
position: fixed;
z-index: 70;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
background: rgba(7, 3, 43, 0.68);
backdrop-filter: blur(2px);
}
.info-modal {
position: relative;
width: min(294px, calc(100vw - 40px));
max-height: min(72vh, 520px);
overflow: auto;
padding: 24px 18px 20px;
border: 2px solid rgba(255, 255, 255, 0.84);
border-radius: 12px;
background: linear-gradient(
150deg,
rgba(160, 166, 235, 0.98),
rgba(91, 89, 174, 0.98)
);
box-shadow: var(--hy-theme-modal-shadow);
}
.info-modal h2 {
margin: 0 0 10px;
font-size: 17px;
text-align: center;
}
.rule-modal li {
margin: 5px 0;
font-size: 13px;
font-weight: 700;
line-height: 1.42;
}
.modal-close {
position: absolute;
z-index: 2;
top: 10px;
right: 12px;
width: 28px;
height: 28px;
padding: 0;
border: 0;
background: transparent;
color: #fff;
font-size: 24px;
line-height: 26px;
cursor: pointer;
}
.result-modal {
position: relative;
width: min(351px, calc(100vw - 20px));
min-height: 317px;
padding: 37px 13px 22px;
background: url('./assets/layers/reward-panel.png') center / 100% 100%
no-repeat;
filter: drop-shadow(0 18px 26px rgba(12, 2, 66, 0.48));
color: #fff;
text-align: center;
}
.result-modal h2 {
position: absolute;
top: 17px;
right: 35px;
left: 35px;
margin: 0;
font-family: 'Playball', Georgia, serif;
font-size: 28px;
font-style: italic;
line-height: 42px;
text-shadow: 0 2px 3px #2e38a4;
}
.result-rewards {
display: flex;
min-height: 115px;
align-items: flex-start;
justify-content: center;
gap: 5px;
margin-top: 37px;
}
.result-reward {
width: 100px;
}
.result-reward .tier-reward-media {
transform: scale(0.94);
}
.result-reward strong {
display: block;
margin-top: -3px;
overflow: hidden;
color: #44409c;
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.result-modal > p {
min-height: 34px;
margin: 0 15px 5px;
color: #5052a6;
font-family: Georgia, serif;
font-size: 11px;
font-style: italic;
font-weight: 700;
line-height: 1.35;
}
.result-confirm {
width: 200px;
height: 53px;
padding: 0 20px;
border: 0;
background: url('./assets/layers/reward-status-frame.png') center / 200px
53px no-repeat;
color: #fff;
font-family: 'Playball', Georgia, serif;
font-size: 25px;
font-style: italic;
font-weight: 700;
text-shadow: 0 2px 3px #9b5700;
cursor: pointer;
}
.records-modal {
width: min(335px, calc(100vw - 32px));
background: linear-gradient(
160deg,
rgba(76, 65, 190, 0.98),
rgba(39, 27, 132, 0.98)
);
}
.records-loading {
display: flex;
min-height: 160px;
align-items: center;
justify-content: center;
gap: 10px;
}
.records-loading .loading-spinner {
width: 24px;
height: 24px;
}
.records-list {
display: grid;
margin: 0;
padding: 0;
gap: 8px;
list-style: none;
}
.record-item {
display: grid;
min-height: 60px;
align-items: center;
padding: 7px 9px;
grid-template-columns: 44px minmax(0, 1fr);
gap: 9px;
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 10px;
background: rgba(255, 255, 255, 0.09);
}
.record-item img {
width: 44px;
height: 44px;
border-radius: 8px;
object-fit: cover;
}
.record-item .media-placeholder {
width: 44px;
height: 44px;
margin: 0;
}
.record-item strong,
.record-item small {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.record-item strong {
font-size: 13px;
}
.record-item small {
margin-top: 4px;
color: #d9d8ff;
font-size: 10px;
}
html[dir='rtl'] .side-actions {
right: auto;
left: -45px;
transform: scaleX(-1);
}
html[dir='rtl'] .side-action span {
display: block;
transform: scaleX(-1);
}
html[dir='rtl'] .modal-close {
right: auto;
left: 12px;
}
html[dir='rtl'] .records-link {
margin-right: auto;
margin-left: 48px;
}
html[dir='rtl'] .hero-brand h1 {
direction: ltr;
}
@media (max-width: 374px) {
.game-king-app {
width: 375px;
margin-left: 50%;
transform: translateX(-50%) scale(calc(100vw / 375));
transform-origin: top center;
}
body {
min-height: calc(100vh * 375 / 320);
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}