@mundogamernetwork/shared-ui 1.1.67 → 1.1.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/keys/KeyBrowser.vue +2 -2
- package/components/keys/KeyCampaignDashboardCard.vue +7 -7
- package/components/keys/KeyCampaignsCarousel.vue +190 -0
- package/locales/de.json +22 -2
- package/locales/en.json +22 -2
- package/locales/pt-BR.json +22 -2
- package/locales/ro.json +22 -2
- package/package.json +1 -1
- package/pages/key-campaign/[slug].vue +16 -1
- package/pages/key-campaigns/[slug].vue +44 -38
- package/pages/key-campaigns/index.vue +22 -22
- package/pages/key-campaigns/redeem-key-approved.vue +311 -0
- package/pages/key-campaigns/redeem-key.vue +320 -0
- package/services/campaignService.ts +12 -4
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
<div class="days" v-else></div>
|
|
191
191
|
<span>
|
|
192
192
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
|
|
193
|
-
<path d="M13.3333 4.1112L12.8666 3.64453L11.9333 4.57786L10.9333 3.64453L8.33329 4.1112L2.66663 9.77786L7.19996 14.3112L12.8666 8.64453L13.3333 6.04453L12.4 5.1112L13.3333 4.1112ZM12.6 6.24453L12.2666 8.3112L7.19996 13.3779L3.59996 9.77786L8.66663 4.7112L10.7333 4.3112L11.4666 5.04453L11 5.5112L10.5333 5.04453L9.99996 5.57786L11.4 6.97786L11.8666 6.5112L11.4 6.04453L11.8666 5.57786L12.6 6.24453Z" fill="var(--key-accent, #D297FF)" />
|
|
193
|
+
<path d="M13.3333 4.1112L12.8666 3.64453L11.9333 4.57786L10.9333 3.64453L8.33329 4.1112L2.66663 9.77786L7.19996 14.3112L12.8666 8.64453L13.3333 6.04453L12.4 5.1112L13.3333 4.1112ZM12.6 6.24453L12.2666 8.3112L7.19996 13.3779L3.59996 9.77786L8.66663 4.7112L10.7333 4.3112L11.4666 5.04453L11 5.5112L10.5333 5.04453L9.99996 5.57786L11.4 6.97786L11.8666 6.5112L11.4 6.04453L11.8666 5.57786L12.6 6.24453Z" fill="var(--key-accent, var(--key-accent, var(--primary, #D297FF)))" />
|
|
194
194
|
</svg>
|
|
195
195
|
{{ card.type }}
|
|
196
196
|
</span>
|
|
@@ -737,7 +737,7 @@ onUnmounted(() => {
|
|
|
737
737
|
display: inline-block;
|
|
738
738
|
width: 20px;
|
|
739
739
|
height: 20px;
|
|
740
|
-
border: 2px solid var(--key-accent, #
|
|
740
|
+
border: 2px solid var(--key-accent, var(--key-accent, var(--primary, #D297FF)));
|
|
741
741
|
border-radius: 50%;
|
|
742
742
|
border-top-color: #fff;
|
|
743
743
|
animation: spin 1s ease-in-out infinite;
|
|
@@ -775,7 +775,7 @@ onUnmounted(() => {
|
|
|
775
775
|
position: absolute;
|
|
776
776
|
bottom: 8px;
|
|
777
777
|
right: 8px;
|
|
778
|
-
background: var(--key-accent-dark, rgba(107, 21, 172, 0.9));
|
|
778
|
+
background: var(--key-accent-dark, var(--key-accent-bg, rgba(107, 21, 172, 0.9)));
|
|
779
779
|
color: #fff;
|
|
780
780
|
font-size: 12px;
|
|
781
781
|
font-weight: 600;
|
|
@@ -790,7 +790,7 @@ onUnmounted(() => {
|
|
|
790
790
|
position: absolute;
|
|
791
791
|
top: 8px;
|
|
792
792
|
left: 8px;
|
|
793
|
-
background: rgba(234, 179, 8, 0.9);
|
|
793
|
+
background: var(--exclusive-badge-bg, rgba(234, 179, 8, 0.9));
|
|
794
794
|
color: #000;
|
|
795
795
|
font-size: 10px;
|
|
796
796
|
font-weight: 700;
|
|
@@ -806,15 +806,15 @@ onUnmounted(() => {
|
|
|
806
806
|
.level-badge {
|
|
807
807
|
top: auto;
|
|
808
808
|
bottom: 8px;
|
|
809
|
-
background: rgba(210, 151, 255, 0.92);
|
|
810
|
-
color: #
|
|
809
|
+
background: var(--level-badge-bg, rgba(210, 151, 255, 0.92));
|
|
810
|
+
color: var(--key-accent-ink, #13161C);
|
|
811
811
|
}
|
|
812
812
|
|
|
813
813
|
.early-access-badge {
|
|
814
814
|
position: absolute;
|
|
815
815
|
top: 8px;
|
|
816
816
|
left: 8px;
|
|
817
|
-
background: var(--key-accent-dark, rgba(107, 21, 172, 0.9));
|
|
817
|
+
background: var(--key-accent-dark, var(--key-accent-bg, rgba(107, 21, 172, 0.9)));
|
|
818
818
|
color: #fff;
|
|
819
819
|
font-size: 10px;
|
|
820
820
|
font-weight: 700;
|
|
@@ -827,13 +827,13 @@ onUnmounted(() => {
|
|
|
827
827
|
i { font-size: 10px; }
|
|
828
828
|
}
|
|
829
829
|
|
|
830
|
-
.exclusive-lock { background: rgba(234, 179, 8, 0.6) !important; }
|
|
830
|
+
.exclusive-lock { background: var(--exclusive-lock-bg, rgba(234, 179, 8, 0.6)) !important; }
|
|
831
831
|
|
|
832
832
|
.early-access-lock-overlay,
|
|
833
833
|
.exclusive-lock-overlay {
|
|
834
834
|
position: absolute;
|
|
835
835
|
inset: 0;
|
|
836
|
-
background: rgba(0, 0, 0, 0.72);
|
|
836
|
+
background: var(--overlay-dark-strong, rgba(0, 0, 0, 0.72));
|
|
837
837
|
display: flex;
|
|
838
838
|
flex-direction: column;
|
|
839
839
|
align-items: center;
|
|
@@ -842,13 +842,13 @@ onUnmounted(() => {
|
|
|
842
842
|
padding: 12px;
|
|
843
843
|
text-align: center;
|
|
844
844
|
|
|
845
|
-
i { font-size: 24px; color: var(--key-accent, #D297FF); }
|
|
845
|
+
i { font-size: 24px; color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
|
|
846
846
|
.lock-label { color: #fff; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
847
|
-
.lock-countdown { color: var(--key-accent, #D297FF); font-size: 12px; font-weight: 600; }
|
|
848
|
-
.lock-cta { color: #EAB308; font-size: 11px; font-weight: 600; }
|
|
847
|
+
.lock-countdown { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); font-size: 12px; font-weight: 600; }
|
|
848
|
+
.lock-cta { color: var(--exclusive-badge-color, #EAB308); font-size: 11px; font-weight: 600; }
|
|
849
849
|
}
|
|
850
850
|
|
|
851
|
-
.exclusive-lock-overlay i { color: #EAB308; }
|
|
851
|
+
.exclusive-lock-overlay i { color: var(--exclusive-badge-color, #EAB308); }
|
|
852
852
|
|
|
853
853
|
.upgrade-btn {
|
|
854
854
|
display: flex;
|
|
@@ -952,7 +952,7 @@ onUnmounted(() => {
|
|
|
952
952
|
cursor: pointer;
|
|
953
953
|
}
|
|
954
954
|
|
|
955
|
-
span.active { background: var(--key-accent, #6b15ac); }
|
|
955
|
+
span.active { background: var(--key-accent, var(--key-accent, var(--primary, #6b15ac))); }
|
|
956
956
|
}
|
|
957
957
|
}
|
|
958
958
|
|
|
@@ -997,8 +997,8 @@ onUnmounted(() => {
|
|
|
997
997
|
}
|
|
998
998
|
|
|
999
999
|
.header-left .btn.tertiary.active {
|
|
1000
|
-
background-color: var(--key-accent, #D297FF);
|
|
1001
|
-
color: #
|
|
1000
|
+
background-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF)));
|
|
1001
|
+
color: var(--key-accent-ink, #13161C);
|
|
1002
1002
|
}
|
|
1003
1003
|
|
|
1004
1004
|
.platform-select {
|
|
@@ -1012,11 +1012,11 @@ onUnmounted(() => {
|
|
|
1012
1012
|
cursor: pointer;
|
|
1013
1013
|
|
|
1014
1014
|
option {
|
|
1015
|
-
background: var(--bg-primary, #
|
|
1015
|
+
background: var(--bg-primary, var(--key-accent-ink, #13161C));
|
|
1016
1016
|
color: var(--title-fg);
|
|
1017
1017
|
}
|
|
1018
1018
|
|
|
1019
|
-
&:focus { outline: none; border-color: var(--key-accent, #D297FF); }
|
|
1019
|
+
&:focus { outline: none; border-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
|
|
1020
1020
|
}
|
|
1021
1021
|
|
|
1022
1022
|
.filter-divider {
|
|
@@ -1078,7 +1078,7 @@ onUnmounted(() => {
|
|
|
1078
1078
|
|
|
1079
1079
|
&:not(.unavailable):hover {
|
|
1080
1080
|
transform: translateY(-4px);
|
|
1081
|
-
box-shadow: 0 8px 24px rgba(107, 21, 172, 0.15);
|
|
1081
|
+
box-shadow: 0 8px 24px var(--key-accent-shadow, rgba(107, 21, 172, 0.15));
|
|
1082
1082
|
}
|
|
1083
1083
|
|
|
1084
1084
|
.card-header {
|
|
@@ -1116,7 +1116,7 @@ onUnmounted(() => {
|
|
|
1116
1116
|
display: flex;
|
|
1117
1117
|
align-items: center;
|
|
1118
1118
|
gap: 4px;
|
|
1119
|
-
span { color: var(--key-accent, #
|
|
1119
|
+
span { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); font-size: 16px; font-weight: 600; }
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
1122
|
span {
|
|
@@ -1168,7 +1168,7 @@ onUnmounted(() => {
|
|
|
1168
1168
|
justify-content: center;
|
|
1169
1169
|
cursor: pointer;
|
|
1170
1170
|
flex-shrink: 0;
|
|
1171
|
-
&:hover { border-color: var(--key-accent, #D297FF); color: var(--key-accent, #D297FF); }
|
|
1171
|
+
&:hover { border-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
|
|
1172
1172
|
i { font-size: 14px; }
|
|
1173
1173
|
}
|
|
1174
1174
|
}
|
|
@@ -1187,7 +1187,7 @@ onUnmounted(() => {
|
|
|
1187
1187
|
font-size: 12px;
|
|
1188
1188
|
color: var(--title-fg);
|
|
1189
1189
|
font-weight: 400;
|
|
1190
|
-
span { color: var(--key-accent, #
|
|
1190
|
+
span { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
|
|
1191
1191
|
}
|
|
1192
1192
|
}
|
|
1193
1193
|
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, inject, onMounted } from "vue"
|
|
3
|
+
import { useRoute, navigateTo } from "#app"
|
|
4
|
+
import { useNuxtApp } from "#app"
|
|
5
|
+
import { revealKey, fetchKeyRequestById } from "../../services/campaignService"
|
|
6
|
+
|
|
7
|
+
const route = useRoute()
|
|
8
|
+
const { $i18n } = useNuxtApp()
|
|
9
|
+
const locale = $i18n.locale
|
|
10
|
+
|
|
11
|
+
const currentUser = inject<any>("currentUser", null)
|
|
12
|
+
const loginUrl = inject<string>("loginUrl", "/")
|
|
13
|
+
|
|
14
|
+
const requestId = Number(route.query.requestId)
|
|
15
|
+
const keyItemsParam = route.query.keyItems as string | undefined
|
|
16
|
+
|
|
17
|
+
const loading = ref(true)
|
|
18
|
+
const revealing = ref(false)
|
|
19
|
+
const keyCode = ref<string | null>(null)
|
|
20
|
+
const error = ref("")
|
|
21
|
+
const requestData = ref<any>(null)
|
|
22
|
+
const copied = ref(false)
|
|
23
|
+
|
|
24
|
+
onMounted(async () => {
|
|
25
|
+
if (!currentUser) {
|
|
26
|
+
const returnTo = typeof window !== "undefined" ? window.location.href : ""
|
|
27
|
+
navigateTo(`${loginUrl}?redirect_to=${encodeURIComponent(returnTo)}`, { external: true })
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if (!requestId) {
|
|
31
|
+
navigateTo(`/${locale.value}/key-campaigns`)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetchKeyRequestById(requestId)
|
|
36
|
+
requestData.value = res?.data?.data || res?.data || null
|
|
37
|
+
} catch {
|
|
38
|
+
error.value = $i18n.t("keys.campaigns.error_loading")
|
|
39
|
+
} finally {
|
|
40
|
+
loading.value = false
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
async function reveal() {
|
|
45
|
+
revealing.value = true
|
|
46
|
+
error.value = ""
|
|
47
|
+
try {
|
|
48
|
+
const res = await revealKey(requestId)
|
|
49
|
+
const data = res?.data?.data || res?.data || null
|
|
50
|
+
keyCode.value = data?.key || data?.code || data?.value || null
|
|
51
|
+
if (!keyCode.value) {
|
|
52
|
+
error.value = $i18n.t("keys.campaigns.error_reveal")
|
|
53
|
+
}
|
|
54
|
+
} catch (e: any) {
|
|
55
|
+
error.value = e?.response?.data?.message || $i18n.t("keys.campaigns.error_reveal")
|
|
56
|
+
} finally {
|
|
57
|
+
revealing.value = false
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function copyCode() {
|
|
62
|
+
if (!keyCode.value) return
|
|
63
|
+
try {
|
|
64
|
+
await navigator.clipboard.writeText(keyCode.value)
|
|
65
|
+
copied.value = true
|
|
66
|
+
setTimeout(() => { copied.value = false }, 2000)
|
|
67
|
+
} catch {
|
|
68
|
+
// fallback: select text
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function goBack() {
|
|
73
|
+
if (typeof window !== "undefined" && window.history.length > 1) {
|
|
74
|
+
window.history.back()
|
|
75
|
+
} else {
|
|
76
|
+
navigateTo(`/${locale.value}/key-campaigns`)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<template>
|
|
82
|
+
<div id="shared-redeem-key-approved">
|
|
83
|
+
<div class="container">
|
|
84
|
+
<div class="header">
|
|
85
|
+
<NuxtLink @click.prevent="goBack" class="back">
|
|
86
|
+
<MGIcon size="2x" icon="chevron-left" />
|
|
87
|
+
<span>{{ $t("keys.campaigns.back") }}</span>
|
|
88
|
+
</NuxtLink>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div v-if="loading" class="state">
|
|
92
|
+
<div class="skeleton" v-for="i in 2" :key="i" />
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div v-else-if="error && !keyCode" class="state error">{{ error }}</div>
|
|
96
|
+
|
|
97
|
+
<div v-else class="content">
|
|
98
|
+
<div class="title-bar">
|
|
99
|
+
<MGIcon icon="version" size="2x" class="title-icon" />
|
|
100
|
+
<div>
|
|
101
|
+
<h3>{{ $t("keys.campaigns.status_key.reveal_key") }}</h3>
|
|
102
|
+
<p v-if="requestData?.key?.name" class="campaign-name">{{ requestData.key.name }}</p>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!-- Key not yet revealed -->
|
|
107
|
+
<div v-if="!keyCode" class="reveal-block">
|
|
108
|
+
<p class="hint">{{ $t("keys.campaigns.reveal_hint") }}</p>
|
|
109
|
+
<button
|
|
110
|
+
class="btn"
|
|
111
|
+
:class="{ disabled: revealing }"
|
|
112
|
+
:disabled="revealing"
|
|
113
|
+
@click="reveal"
|
|
114
|
+
>
|
|
115
|
+
{{ revealing ? $t("keys.campaigns.revealing") : $t("keys.campaigns.status_key.reveal_key") }}
|
|
116
|
+
</button>
|
|
117
|
+
<div v-if="error" class="req-error">{{ error }}</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<!-- Key revealed -->
|
|
121
|
+
<div v-else class="key-block">
|
|
122
|
+
<div class="key-label">{{ $t("keys.campaigns.your_key") }}</div>
|
|
123
|
+
<div class="key-code-row">
|
|
124
|
+
<span class="key-code">{{ keyCode }}</span>
|
|
125
|
+
<button class="copy-btn" @click="copyCode">
|
|
126
|
+
<MGIcon :icon="copied ? 'check' : 'copy'" size="1x" />
|
|
127
|
+
{{ copied ? $t("keys.campaigns.copied") : $t("keys.campaigns.copy") }}
|
|
128
|
+
</button>
|
|
129
|
+
</div>
|
|
130
|
+
<p class="redeem-info">{{ $t("keys.campaigns.redeem_on_platform") }}</p>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<!-- Request info -->
|
|
134
|
+
<div v-if="requestData" class="info-grid">
|
|
135
|
+
<div class="info-row" v-if="requestData.status_request?.name">
|
|
136
|
+
<span class="info-label">{{ $t("keys.campaigns.status") }}</span>
|
|
137
|
+
<span class="info-val">{{ requestData.status_request.name }}</span>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="info-row" v-if="requestData.key?.name">
|
|
140
|
+
<span class="info-label">{{ $t("keys.campaigns.campaign.title") }}</span>
|
|
141
|
+
<span class="info-val">{{ requestData.key.name }}</span>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</template>
|
|
148
|
+
|
|
149
|
+
<style lang="scss" scoped>
|
|
150
|
+
#shared-redeem-key-approved {
|
|
151
|
+
align-items: center;
|
|
152
|
+
width: 100%;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
overflow: auto;
|
|
155
|
+
height: 100%;
|
|
156
|
+
|
|
157
|
+
.container { max-width: 680px !important; padding: 32px 16px 64px; }
|
|
158
|
+
|
|
159
|
+
.header {
|
|
160
|
+
margin-bottom: 24px;
|
|
161
|
+
.back {
|
|
162
|
+
display: inline-flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: 8px;
|
|
165
|
+
font-size: 14px;
|
|
166
|
+
color: var(--secondary-info-fg);
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
text-decoration: none;
|
|
169
|
+
&:hover { color: var(--card-article-title); }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.state {
|
|
174
|
+
display: flex;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
align-items: center;
|
|
177
|
+
gap: 12px;
|
|
178
|
+
padding: 64px 0;
|
|
179
|
+
text-align: center;
|
|
180
|
+
color: var(--secondary-info-fg);
|
|
181
|
+
&.error { color: var(--danger, #e53935); }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.skeleton {
|
|
185
|
+
width: 100%;
|
|
186
|
+
height: 48px;
|
|
187
|
+
background: var(--bg-app-badge);
|
|
188
|
+
animation: pulse 1.4s ease-in-out infinite;
|
|
189
|
+
& + & { margin-top: 8px; }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.content { display: flex; flex-direction: column; gap: 28px; }
|
|
193
|
+
|
|
194
|
+
.title-bar {
|
|
195
|
+
display: flex;
|
|
196
|
+
align-items: flex-start;
|
|
197
|
+
gap: 14px;
|
|
198
|
+
.title-icon { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); margin-top: 2px; }
|
|
199
|
+
h3 { font-size: 20px; font-weight: 700; color: var(--card-article-title); margin: 0 0 4px; }
|
|
200
|
+
.campaign-name { font-size: 13px; color: var(--secondary-info-fg); margin: 0; }
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.reveal-block {
|
|
204
|
+
display: flex;
|
|
205
|
+
flex-direction: column;
|
|
206
|
+
gap: 16px;
|
|
207
|
+
padding: 24px;
|
|
208
|
+
background: var(--bg-app-badge);
|
|
209
|
+
border: 1px solid var(--button-secondary-default-bg);
|
|
210
|
+
|
|
211
|
+
.hint { font-size: 14px; color: var(--secondary-info-fg); margin: 0; }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.key-block {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-direction: column;
|
|
217
|
+
gap: 12px;
|
|
218
|
+
padding: 24px;
|
|
219
|
+
background: var(--bg-app-badge);
|
|
220
|
+
border: 1px solid var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.key-label {
|
|
224
|
+
font-size: 12px;
|
|
225
|
+
font-weight: 600;
|
|
226
|
+
text-transform: uppercase;
|
|
227
|
+
letter-spacing: 0.5px;
|
|
228
|
+
color: var(--secondary-info-fg);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.key-code-row {
|
|
232
|
+
display: flex;
|
|
233
|
+
align-items: center;
|
|
234
|
+
gap: 12px;
|
|
235
|
+
flex-wrap: wrap;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.key-code {
|
|
239
|
+
font-size: 20px;
|
|
240
|
+
font-weight: 700;
|
|
241
|
+
font-family: monospace;
|
|
242
|
+
letter-spacing: 2px;
|
|
243
|
+
color: var(--card-article-title);
|
|
244
|
+
word-break: break-all;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.copy-btn {
|
|
248
|
+
display: inline-flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
gap: 6px;
|
|
251
|
+
padding: 6px 14px;
|
|
252
|
+
font-size: 13px;
|
|
253
|
+
font-weight: 600;
|
|
254
|
+
background: transparent;
|
|
255
|
+
border: 1px solid var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
256
|
+
color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
transition: background 0.15s;
|
|
259
|
+
&:hover { background: var(--key-accent-subtle-bg, rgba(210, 151, 255, 0.1)); }
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.redeem-info {
|
|
263
|
+
font-size: 12px;
|
|
264
|
+
color: var(--secondary-info-fg);
|
|
265
|
+
margin: 0;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.req-error { font-size: 13px; color: var(--danger, #e53935); }
|
|
269
|
+
|
|
270
|
+
.info-grid {
|
|
271
|
+
display: flex;
|
|
272
|
+
flex-direction: column;
|
|
273
|
+
gap: 8px;
|
|
274
|
+
padding-top: 8px;
|
|
275
|
+
border-top: 1px solid var(--button-secondary-default-bg);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.info-row {
|
|
279
|
+
display: flex;
|
|
280
|
+
gap: 12px;
|
|
281
|
+
font-size: 13px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.info-label {
|
|
285
|
+
color: var(--secondary-info-fg);
|
|
286
|
+
min-width: 100px;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.info-val { color: var(--card-article-title); }
|
|
290
|
+
|
|
291
|
+
.btn {
|
|
292
|
+
align-self: flex-start;
|
|
293
|
+
padding: 0 28px;
|
|
294
|
+
height: 44px;
|
|
295
|
+
font-size: 14px;
|
|
296
|
+
font-weight: 700;
|
|
297
|
+
background: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
298
|
+
color: #fff;
|
|
299
|
+
border: none;
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
transition: opacity 0.15s;
|
|
302
|
+
&.disabled, &:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
303
|
+
&:not(.disabled):hover { opacity: 0.85; }
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@keyframes pulse {
|
|
308
|
+
0%, 100% { opacity: 1; }
|
|
309
|
+
50% { opacity: 0.4; }
|
|
310
|
+
}
|
|
311
|
+
</style>
|